このページでは

Qt Quick 3D - XR 入力例(簡易版)

Qt Quick 3D XR におけるコントローラー入力のデモです。

XRコントローラーの光線が、色付きのボタンがあるUIパネルを指し示しているティーポット

この例では、Qt Quick 3D XRの低レベル入力APIを使用して、シーン内の2Dおよび3Dオブジェクトとインタラクションを行う方法を示します。xr_simple例の基本的な構成に従っています。

コントローラー入力

この例では、XrController の位置からray picking を行います:

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
            }
        }
    }
}

これにより、以下の処理が行われます:

  • 何かに当たった場合、pickRay の長さを変更して、当たった対象に接触するようにします。pickRay は、ユーザーが狙っている位置を示す半透明の円錐(先細りの円柱)です。また、cursorSphere を光線が当たった位置に移動させます。(cursorSphere は、XrView の子オブジェクトである半透明の球体です)。
  • hitObject プロパティには、ヒットしたオブジェクトを設定します。

また、コントローラーの一般的な表現として、黒い円柱を使用します。

この例では、ファイル `ExampleButton.qml` にシンプルな3Dプッシュボタンを作成しました。(ボタンの動作の詳細については、ここでは説明しません。)トリガーの押下に応答するために、XrInputAction を作成します:

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
        }
    }
}

rightTrigger アクションは、ハンドトラッキングと各種コントローラーの両方をサポートするため、複数の異なるIDに反応します。アクションがトリガーされると、上記で設定したhitObject がExampleButton 型であるかどうかがチェックされます。その場合、ボタンがアクティブになります。

3Dコントローラーが2Dコンテンツと連携できるようにするには、両者をマッピングするためのXrVirtualMouse を追加する必要があります:

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
}

まず、サムスティックの水平位置と垂直位置を検出するためのアクションを2つ追加します。次に、XrController を位置ソースとして使用して、XrVirtualMouse を作成します。先ほど作成したrightTrigger アクションを使用してマウスのクリック/リリースを生成し、サムスティックアクションを使用してマウスホイールイベントを生成します。

最後に、pickRay がオブジェクトに衝突した際に、ハプティックフィードバックを追加します:

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

このハプティック効果は、pickRay.hit プロパティがfalse からtrue に変わるたびにトリガーされます。

XrItem

3Dシーンに2Dユーザーインターフェースを埋め込む通常の方法はXRでも機能しますが、単位サイズが1センチメートルであるため、それらのユーザーインターフェースを実用的に使用するにはスケーリングする必要があります。XrItem 型を使用すると、3Dアイテムの物理サイズと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
    ...
        }
    }

XrItem を3次元空間に配置し、幅75 cm、高さ100 cmに設定します。次に、コンテンツアイテムとして長方形を追加し、300 × 400単位に設定します。残りのQt Quick UI要素は、通常の方法で長方形の子要素として追加されるため、ここでは省略します。 2Dコンテンツは、XrItem を埋めるように自動的に拡大縮小されます。

サンプルプロジェクト @ 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.