Как реализовать обработку жестов двумя пальцами для Qt3D Camera
FOV?
Есть FirstPersonCameraController
а также OrbitCameraController
контроллеры камеры, которые обрабатывают события мыши / сенсорной панели. Последние даже имеют zoomLimit
свойство, но его значение не то, что мне нужно, чтобы увеличить сцену (изнутри кубической карты положение камеры фиксируется на (0, 0, 0)
). Я использую первый. Он правильно обрабатывает события перетаскивания мышью и касания одним пальцем, но не обрабатывает жест, похожий на щепотку двумя пальцами.
Могу ли я настроить простым способом PinchArea
взаимодействовать с Qt3D«s Camera
? Или же Qt QuickAPI в этом смысле ортогональны Qt3DAPI?
Используйте событие pinchUpdated PinchArea, чтобы найти информацию о Pinch: в соответствии с документом
Параметр пинч предоставляет информацию о жесте пинч,
в том числе масштаб, центр и угол защемления. Эти значения
отражать изменения только с начала текущего жеста, и
поэтому не ограничены минимальными и максимальными
щепотка собственности.
Таким образом, вы должны быть в состоянии сделать что-то вроде:
Camera {
id: myCamera
}
PinchArea {
onPinchUpdated: {
myCamera.fieldOfView = pinch.scale*someFactor
}
}
Это может быть сделано в любом имеющемся у вас QML, который имеет доступ к Pinch и камере.
Если это пользовательский скрипт, вы всегда можете передать камеру как свойство
property Camera myCamera
Я закончил с комбинацией PinchArea
а также MouseArea
:
import QtQml 2.2
import QtQuick 2.9
import QtQuick.Scene3D 2.0
import Qt3D.Core 2.9
import Qt3D.Extras 2.9
import Qt3D.Render 2.9
import Qt3D.Input 2.1
import Qt3D.Logic 2.0
import PanoEntity 1.0
import Utility 1.0
Item {
property url panorama
onPanoramaChanged: {
if (panorama.toString().length !== 0) {
if (panoEntity.setPanorama(panorama)) {
basicCamera.position = Qt.vector3d(0.0, 0.0, 0.0)
basicCamera.upVector = Qt.vector3d(0.0, 0.0, 1.0)
basicCamera.viewCenter = panoEntity.pano.dir
pinchArea.updateFov(defaultFov)
}
}
}
property Image previewImage
property real fovMin: 20.0
property real defaultFov: 60.0
property real fovMax: 90.0
property real sensitivity: 1.5
property real pinchSensitivity: 0.5
Scene3D {
id: scene3d
anchors.fill: parent
aspects: ["render", "input", "logic"]
cameraAspectRatioMode: Scene3D.AutomaticAspectRatio // basicCamera.aspectRatio = width / height
multisample: true
Entity {
Camera {
id: basicCamera
projectionType: CameraLens.PerspectiveProjection
nearPlane: 0.1
farPlane: 2.0 * Math.SQRT2
}
RenderSettings {
id: renderSettings
renderPolicy: scene3d.visible ? RenderSettings.Always : RenderSettings.OnDemand
ForwardRenderer {
camera: basicCamera
clearColor: "transparent"}
}
InputSettings {
id: inputSettings
}
components: [renderSettings, inputSettings]
PanoEntity {
id: panoEntity
MemoryBarrier {
waitFor: MemoryBarrier.All
}
}
}
}
PinchArea {
id: pinchArea
anchors.fill: parent
function updateFov(newFov) {
if (newFov > fovMax) {
newFov = fovMax
} else if (newFov < fovMin) {
newFov = fovMin
}
var eps = 1.0 / 60.0
if (Math.abs(basicCamera.fieldOfView - newFov) > eps) {
basicCamera.fieldOfView = newFov
zoomer.fov = newFov
}
}
function updatePinch(pinch) {
updateFov(basicCamera.fieldOfView * (1.0 + (pinch.previousScale - pinch.scale) * pinchSensitivity))
}
onPinchUpdated: {
updatePinch(pinch)
}
onPinchFinished: {
updatePinch(pinch)
}
MouseArea {
anchors.fill: parent
propagateComposedEvents: true
property point startPoint
function updateView(mouse) {
basicCamera.pan((startPoint.x - mouse.x) * sensitivity * basicCamera.fieldOfView / width, Qt.vector3d(0.0, 0.0, 1.0))
basicCamera.tilt((mouse.y - startPoint.y) * sensitivity * basicCamera.fieldOfView / height)
startPoint = Qt.point(mouse.x, mouse.y)
}
onPressed: {
startPoint = Qt.point(mouse.x, mouse.y)
}
onPositionChanged: {
updateView(mouse)
}
onReleased: {
updateView(mouse)
}
}
}
Zoomer {
id: zoomer
fovMax: parent.fovMax
defaultFov: parent.defaultFov
fovMin: parent.fovMin
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: 45
onFovChanged: {
pinchArea.updateFov(fov);
}
}
Shortcut {
context: Qt.WindowShortcut
enabled: scene3d.visible
sequence: StandardKey.Save
onActivated: {
panoEntity.pano.dir = basicCamera.viewCenter
panoEntity.pano.up = basicCamera.upVector
panoEntity.pano.version = 7
if (!panoEntity.updatePanorama()) {
console.log("Unable to update panorama %1".arg(panorama))
} else if (previewImage && Utility.fileExists(previewImage.source)) {
scene3d.grabToImage(function(grabResult) {
if (!grabResult.saveToFile(Utility.toLocalFile(previewImage.source))) {
console.log("Unable save preview to file: %1".arg(previewImage.source))
}
}, Qt.size(512, 512))
}
}
}
}