如何围绕网格旋转相机

问题描述 投票:0回答:4

使用 Qt/QML/C++,我尝试构建一个非常基本的 3D 场景来围绕网格对象旋转相机。

主.cpp

#include <Qt3DQuickExtras/qt3dquickwindow.h>
#include <Qt3DQuick/QQmlAspectEngine>

#include <QGuiApplication>
#include <QtQml>

int main(int argc, char **argv)
{
    QGuiApplication app(argc, argv);
    Qt3DExtras::Quick::Qt3DQuickWindow view;

    // Expose the window as a context property so we can set the aspect ratio
    view.engine()->qmlEngine()->rootContext()->setContextProperty("_window", &view);
    view.setSource(QUrl("qrc:/main.qml"));
    view.setWidth(800);
    view.setHeight(600);
    view.show();

    return app.exec();
}

main.qml

import Qt3D.Core 2.0
import Qt3D.Render 2.0
import Qt3D.Input 2.0
import Qt3D.Extras 2.0

Entity {
    id: sceneRoot

    Camera {
        id: camera
        projectionType: CameraLens.PerspectiveProjection
        fieldOfView: 25
        aspectRatio: _window.width / _window.height
        nearPlane : 0.1
        farPlane : 1000.0
        position: Qt.vector3d( 0, 0.0, 20.0 )
        upVector: Qt.vector3d( 0.0, 1.0, 0.0 )
        viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 )
    }

    OrbitCameraController {
        camera: camera
    }

    components: [
        RenderSettings {
            activeFrameGraph: ForwardRenderer {
                clearColor: Qt.rgba(0, 0.5, 1, 1)
                camera: camera
            }
        },
        InputSettings { }
    ]

    PhongMaterial {
        id: carMaterial
    }

    Mesh {
        id: carMesh
        source: "resources/aventador.obj"
    }

    Entity {
        id: carEntity
        components: [ carMesh, carMaterial ]
    }
}

如何让相机围绕网格对象旋转?

qt rotation qml mesh qt3d
4个回答
2
投票

OrbitCameraController 允许沿着轨道路径移动相机。要使其围绕网格旋转,您可以将相机的 viewCenter 设置为网格的位置(包含网格的实体的变换的平移)并使用键盘/鼠标来旋转它。

所以添加:

Transform{
        id: carTransform
        translation: Qt.vector3d(5.0, 5.0, 5.0) //random values, choose your own
}

并将变换添加到实体的组件中。 将相机的viewCenter更改为

viewCenter: carTransform.translation

1
投票

您应该使用鼠标或键盘来执行此操作。 当您使用 OrbitCameraControllerFirstPersonCameraController 你无法控制我们。我使用这个 code 而不是 OrbitCameraController。

Entity{
id: root
property Camera camera;
property real dt: 0.001
property real linearSpeed: 1
property real lookSpeed: 500
property real zoomLimit: 0.16

MouseDevice {
    id: mouseDevice
    sensitivity: 0.001 // Make it more smooth
}

MouseHandler {
    id: mh
    readonly property vector3d upVect: Qt.vector3d(0, 1, 0)
    property point lastPos;
    property real pan;
    property real tilt;
    sourceDevice: mouseDevice

    onPanChanged: root.camera.panAboutViewCenter(pan, upVect);
    onTiltChanged: root.camera.tiltAboutViewCenter(tilt);

    onPressed: {
        lastPos = Qt.point(mouse.x, mouse.y);
    }
    onPositionChanged: {
        // You can change the button as you like for rotation or translation
        if (mouse.buttons === 1){ // Left button for rotation
            pan = -(mouse.x - lastPos.x) * dt * lookSpeed;
            tilt = (mouse.y - lastPos.y) * dt * lookSpeed;
        } else if (mouse.buttons === 2) { // Right button for translate
            var rx = -(mouse.x - lastPos.x) * dt * linearSpeed;
            var ry = (mouse.y - lastPos.y) * dt * linearSpeed;
            camera.translate(Qt.vector3d(rx, ry, 0))
        } else if (mouse.buttons === 3) { // Left & Right button for zoom
            ry = (mouse.y - lastPos.y) * dt * linearSpeed
            zoom(ry)
        }

        lastPos = Qt.point(mouse.x, mouse.y)
    }
    onWheel: {
        zoom(wheel.angleDelta.y * dt * linearSpeed)
    }

    function zoom(ry) {
        if (ry > 0 && zoomDistance(camera.position, camera.viewCenter) < zoomLimit) {
            return
        }

        camera.translate(Qt.vector3d(0, 0, ry), Camera.DontTranslateViewCenter)
    }

    function zoomDistance(posFirst, posSecond) {
        return posSecond.minus(posFirst).length()
    }
}}

创建一个新的 qml 类并调用它,例如 SOrbitCameraController 或任何您想要的东西,然后使用它而不是 OrbitCameraController 并将相机带到此类。


0
投票

我知道这是一篇旧帖子,但自从我找到了答案,这也难倒了我,这是我调整的内容:

我发现我需要做的就是将向量设置为零,我用 pyqt 编写,所以我的看起来像这样:

camera.setUpVector(QVector3D(0.0, 0.0, 0.0))

原因是在此之后我能够锁定鼠标右键控件并使用鼠标左键控件围绕网格旋转。


0
投票

我发现了这个有用的信息:

Q_INVOKABLE void tiltAboutViewCenter(float angle);

Q_INVOKABLE void panAboutViewCenter(float angle);

Q_INVOKABLE void panAboutViewCenter(float angle, const QVector3D &axis);

Q_INVOKABLE void rollAboutViewCenter(float angle);

这就是你想要的。

© www.soinside.com 2019 - 2024. All rights reserved.