使用 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 ]
}
}
如何让相机围绕网格对象旋转?
OrbitCameraController 允许沿着轨道路径移动相机。要使其围绕网格旋转,您可以将相机的 viewCenter 设置为网格的位置(包含网格的实体的变换的平移)并使用键盘/鼠标来旋转它。
所以添加:
Transform{
id: carTransform
translation: Qt.vector3d(5.0, 5.0, 5.0) //random values, choose your own
}
并将变换添加到实体的组件中。 将相机的viewCenter更改为
viewCenter: carTransform.translation
您应该使用鼠标或键盘来执行此操作。 当您使用 OrbitCameraController 或 FirstPersonCameraController 你无法控制我们。我使用这个 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 并将相机带到此类。
我知道这是一篇旧帖子,但自从我找到了答案,这也难倒了我,这是我调整的内容:
我发现我需要做的就是将向量设置为零,我用 pyqt 编写,所以我的看起来像这样:
camera.setUpVector(QVector3D(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);
这就是你想要的。