Qt Quick 3D - XR 3D インタラクションの例
Qt Quick の3D XRを使用して、3Dオブジェクトを操作する方法を紹介します。

この例では、シーン内の3Dオブジェクトを移動させたりサイズを変更したりするコンポーネントの作成方法を示します。xr_inputの例と同じレイピッキング戦略を使用しています。
コントローラー入力
この例では、AimController という名前の再利用可能なコンポーネントを作成します。このコンポーネントは、レイピッキングを行ってモデルを選択し、オプションでユーザーが選択したモデルを掴んで移動できるようにします。
AimController カスタムインタラクションを実装するためのシグナルを定義します:
property Model hoveredObject: null
signal objectPressed(obj: Model, pos: vector3d, direction: vector3d)
signal moved(pos: vector3d, direction: vector3d)
signal released()
signal objectGrabbed(obj: Model)ガジェット
抽象コンポーネント `XrGadget` を定義します。これには、handleControllerPress とhandleControllerMove の2つの関数があります。C++ であれば、これらの関数は仮想関数となっていたでしょう。しかし、この例は完全に QML で実装されているため、代わりにサブコンポーネントで処理可能なシグナルを発行します。
たとえば、TranslateGadget は、onMoved シグナルに基づいて、制御対象のオブジェクトをガジェットの軸に沿って移動させます:
onMoved: (pos, dir) => {
let moveDirection = delta.normalized()
let mapped_axis = controlledObject.mapDirectionToScene(axisDirection).normalized()
let dot = mapped_axis.dotProduct(moveDirection)
let offset = mapped_axis.times(delta.length() * dot)
controlledObject.position = originalPos.plus(offset)
}すべてを統合する
GadgetBox というコンポーネントを定義します。このコンポーネントは、どのオブジェクトが選択されているかを追跡し、選択されたオブジェクトの周囲に半透明のボックスを表示するほか、オブジェクトの周囲にガジェットを表示します。選択されたオブジェクトが押されると、GadgetBox が3種類のガジェット(平行移動、回転、サイズ変更)を切り替えます。
main.qml では、AimController からのシグナルに応答し、GadgetBox 内の関数を呼び出します:
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
}また、ホバー中のオブジェクトやガジェットが変更された際には、ハプティックフィードバックを提供します:
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
}
}© 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.