Qt Quick 3D - XR 簡単な入力例

Qt Quick 3D XR のコントローラ入力をデモします。

この例では、Qt Quick 3D XR の低レベル入力 API を使用して、シーン内の 2D および 3D オブジェクトと対話する方法を示します。xr_simpleサンプルの基本構造に従っています。

コントローラ入力

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

XrController {
    id: rightController
    controller: XrController.ControllerRight
    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
        } else {
            pickRay.hit = false
            pickRay.length = 50
            hitObject = null
        }
    }

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

        z: -length/2
        Model {
            eulerRotation.x: 90
            scale: Qt.vector3d(0.02, pickRay.length/100, 0.02)
            source: "#Cylinder"
            materials: PrincipledMaterial { baseColor: pickRay.hit ? "green" : "gray" }
            opacity: 0.5
        }
    }

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

}

これは2つの機能を実行します:

  1. 何かにぶつかったら、pickRay の色を緑に変え、ぶつかったものに触れるように長さを設定する。pickRay は半透明の円柱で、ユーザーがどこを狙っているかを示している。
  2. hitObject というプロパティをヒットしたオブジェクトに設定します。

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

この例では、ファイルExampleButton.qml でシンプルな3Dプッシュボタンを作りました。(ボタンの動作の詳細はここでは説明しません。) トリガーが押されると反応するように、XrInputAction を作成します:

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

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

3Dコントローラーが2Dコンテンツとインタラクションできるようにするには、XrVirtualMouse

XrInputAction {
    id: rightThumbstickX
    hand: XrInputAction.RightHand
    actionId: [XrInputAction.ThumbstickX]
}
XrInputAction {
    id: rightThumbstickY
    hand: XrInputAction.RightHand
    actionId: [XrInputAction.ThumbstickY]
}

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

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

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次元に配置し、幅75cm、高さ100cmに設定する。次に、コンテンツ・アイテムとして長方形を追加し、300 x 400ユニットに設定します。残りのQt Quick UI要素は、通常の方法で矩形の子として追加されるので、ここでは表示しません。2Dコンテンツは、XrItem を埋めるように自動的に拡大縮小されます。

プロジェクト例 @ code.qt.io

© 2025 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.