首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >变焦Qt3D相机

变焦Qt3D相机
EN

Stack Overflow用户
提问于 2017-10-25 09:31:05
回答 2查看 1.5K关注 0票数 4

如何为Qt3D Camera的FOV实现双指捏手势处理?

FirstPersonCameraControllerOrbitCameraController摄像头控制器来处理鼠标/触控板事件。后者甚至有zoomLimit属性,但它的意思不是我需要放大场景(从一个立方体地图中,相机的位置固定到(0, 0, 0))。我用的是前一个。它正确地处理鼠标拖动和单指触摸事件,但不处理两指捏式手势。

我可以用简单的方式定制PinchArea来与Qt3D的Camera交互吗?或者Quick在这个意义上与Qt3D的API是正交的?

EN

回答 2

Stack Overflow用户

发布于 2017-12-11 17:53:33

使用pinchUpdated事件PinchArea查找有关夹点的信息:根据文档

夹点参数提供关于夹点手势的信息,包括夹点的比例、中心和角度。这些值仅反映自当前手势开始以来的更改,因此不受夹点属性中的最小和最大限制的限制。

所以你应该可以这样做:

代码语言:javascript
复制
Camera {
    id: myCamera
}

PinchArea {
    onPinchUpdated: {
        myCamera.fieldOfView = pinch.scale*someFactor
    } 
}

这可以在任何定制的QML中完成,您可以访问夹点和相机。如果是自定义脚本,则可以将摄像机作为属性传递给阿尔瓦兹。

代码语言:javascript
复制
property Camera myCamera
票数 1
EN

Stack Overflow用户

发布于 2017-12-12 07:18:27

最后我把PinchAreaMouseArea结合在一起

代码语言:javascript
复制
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))
            }
        }
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46928812

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档