En esta página

Qt Quick 3D - XR Ejemplo de entrada simple

Demuestra la entrada del controlador en Qt Quick 3D XR.

Tetera con rayo controlador XR apuntando al panel de interfaz de usuario con botones de colores.

Este ejemplo muestra cómo utilizar las APIs de entrada de bajo nivel en Qt Quick 3D XR para interactuar con objetos 2D y 3D en la escena. Sigue la estructura básica del ejemplo xr_simple.

Entrada del controlador

En este ejemplo, hacemos ray picking desde la posición del XrController:

XrController {
    id: rightController
    controller: XrController.RightController
    poseSpace: XrController.AimPose

    property QtObject hitObject

    onRotationChanged: {
        const pickResult = xrView.rayPick(scenePosition, forward)
        if (pickResult.hitType !== PickResult.Null) {
            pickRay.hit = true
            pickRay.length = pickResult.distance
            hitObject = pickResult.objectHit
            cursorSphere.position = pickResult.scenePosition
            cursorSphere.visible = true
        } else {
            pickRay.hit = false
            pickRay.length = 50
            hitObject = null
            cursorSphere.visible = false
        }
    }

    Node {
        id: pickRay
        property real length: 50
        property bool hit: false

        Model {
            eulerRotation.x: -90
            scale: Qt.vector3d(0.005, pickRay.length/100, 0.005)
            source: "#Cone"
            materials: PrincipledMaterial {
                baseColor: rightTrigger.pressed ? "#99aaff" : "#cccccc"
                lighting: PrincipledMaterial.NoLighting
            }
            opacity: 0.8
        }
    }

    Node {
        z: 5
        Model {
            eulerRotation.x: 90
            scale: Qt.vector3d(0.05, 0.10, 0.05)
            source: "#Cylinder"
            materials: PrincipledMaterial {
                baseColor: "black"
                roughness: 0.2
            }
        }
    }
}

Esto realiza las siguientes funciones:

  • Si golpeamos algo, cambiamos la longitud del pickRay para que toque lo que golpeamos. El pickRay es un cono semitransparente (un cilindro cónico) que muestra dónde está apuntando el usuario. También movemos cursorSphere al punto donde impacta el rayo. (cursorSphere es una esfera semitransparente hija de XrView).
  • Establecemos la propiedad hitObject al objeto que golpeamos.

También utilizamos un cilindro negro como representación genérica del controlador.

Para este ejemplo, hemos hecho un simple pulsador 3D en el archivo ExampleButton.qml. (Los detalles de cómo funciona el botón no se explican aquí.) Creamos un XrInputAction para reaccionar a las pulsaciones del gatillo:

XrInputAction {
    id: rightTrigger
    controller: XrInputAction.RightController
    actionId: [XrInputAction.TriggerPressed, XrInputAction.TriggerValue, XrInputAction.IndexFingerPinch]
    onTriggered: {
        const button = rightController.hitObject as ExampleButton
        if (button && button !== panel.activeButton) {
            panel.activeButton = button
        }
    }
}

La acción rightTrigger reacciona a varios IDs diferentes para soportar tanto el seguimiento de la mano como diferentes tipos de controladores. Cuando la acción se dispara, comprueba si el hitObject que establecimos anteriormente es del tipo ExampleButton. En ese caso, el botón se activa.

Para permitir que un controlador 3D interactúe con contenido 2D, necesitamos añadir un XrVirtualMouse para mapear entre ellos:

XrInputAction {
    id: rightThumbstickX
    controller: XrInputAction.RightController
    actionId: [XrInputAction.ThumbstickX]
}
XrInputAction {
    id: rightThumbstickY
    controller: XrInputAction.RightController
    actionId: [XrInputAction.ThumbstickY]
}

XrVirtualMouse {
    view: xrView
    source: rightController
    leftMouseButton: rightTrigger.pressed
    scrollWheelX: rightThumbstickX.value
    scrollWheelY: rightThumbstickY.value
}

Primero añadimos dos acciones más para detectar la posición horizontal y vertical del thumbstick. Luego creamos un XrVirtualMouse, usando el XrController como fuente de posición. Usamos la acción rightTrigger que hicimos antes para generar pulsaciones/retiros del ratón y usamos las acciones del thumbstick para generar eventos de la rueda del ratón.

Por último, añadimos un poco de retroalimentación háptica cuando el pickRay golpea un objeto:

XrHapticFeedback {
    controller: XrHapticFeedback.RightController
    condition: XrHapticFeedback.RisingEdge
    trigger: pickRay.hit
    hapticEffect: XrSimpleHapticEffect {
        amplitude: 0.5
        duration: 10
        frequency: 200
    }
}

El efecto háptico se disparará cada vez que la propiedad pickRay.hit pase de false a true.

XrItem

La forma habitual de incrustar interfaces de usuario 2D en escenas 3D también funciona en XR, pero como la unidad de tamaño es un centímetro, esas interfaces de usuario tendrán que escalarse para ser útiles. El tipo XrItem proporciona una forma cómoda de realizar el escalado automáticamente estableciendo el tamaño físico del elemento 3D y el tamaño lógico de la superficie 2D.

XrItem {
    width: 75
    height: 100
    x: -100
    y: height + table.height + 5
    z: 40
    eulerRotation.y: 45
    color: "transparent"
    contentItem: Rectangle {
        color: Qt.rgba(1, 1, 1, 0.5)
        border.width: 5
        border.color: "lightblue"
        height: 400
        width: 300
        radius: 25
    ...
        }
    }

Colocamos la página XrItem en tres dimensiones y la ajustamos a 75 cm de ancho y 100 cm de alto. A continuación, añadimos un rectángulo como elemento de contenido y establecemos que mida 300 x 400 unidades. El resto de elementos de la interfaz de usuario de Qt Quick se añaden como hijos del rectángulo de la forma habitual y no se muestran aquí. El contenido 2D se escala automáticamente para que llene XrItem.

Proyecto de ejemplo @ code.qt.io

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.