我正在使用 QtQuick 在 Qt Creator 中开发应用程序。此应用程序的目的是在手指的帮助下在 3 个维度上旋转立方体。
我设法开发了与手指运动相关的 Action 创建,但我完全停留在立方体与手指相关的旋转上。
我尝试创建一个关于当前点和先前点以及法向量的方向向量。我在立方体的 x 和 y 方向应用了欧拉旋转,但在某个点,立方体没有按预期旋转。
这是我的应用程序主页的 qml 代码:
main.qml
import QtQuick 2.15
import QtQuick.Window 2.14
import QtQuick3D 1.15
import Qt3D.Input 2.0
import QtQuick.Controls 2.1
import Qt3D.Extras 2.15
Window {
visible: true
width: 640
height: 480
title: qsTr("MouseArea Demo")
MouseArea{
property int previousX: -1
property int previousY: -1
anchors.fill : parent
onPressed: {
previousX = mouseX;
previousY = mouseY;
}
onPositionChanged: {
let direction = Qt.vector2d(mouseX - previousX, mouseY - previousY).normalized();
let normal = Qt.vector2d(direction.y, direction.x).normalized();
console.log("direction : " + direction);
console.log("normal : " + normal);
cube.eulerRotation.x += normal.x * 3;
cube.eulerRotation.y += normal.y * 3;
previousX = mouseX;
previousY = mouseY
}
onReleased: {
previousX = -1;
previousY = -1;
}
}
View3D {
id: view
anchors.fill: parent
camera: camera
renderMode: View3D.Overlay
PerspectiveCamera {
id: camera
position: Qt.vector3d(0, 200, 300)
eulerRotation.x: -30
}
DirectionalLight {
eulerRotation.x: -30
}
Model {
id: cube
visible: true
position: Qt.vector3d(0, 0, 0)
source: "#Cube"
materials: [ DefaultMaterial {
diffuseMap: Texture {
id: texture
source: "../build-colorpicker2d-Desktop_Qt_5_15_2_GCC_64bit-Debug/res.png"
}
}
]
}
}
}
这是一段视频,内容是我 2 天前与您讨论的关于 y 旋转问题的内容。
亲切的问候。
最佳答案
首先,您应该将此添加到您的 .pro
文件中:
QT += qml quick 3dcore 3dinput 3dquick 3dlogic 3dquickextras 3dextras
我在 qml 中有 3 个类:main.qml、RootEntity.qml 和 SOrbitCameraController.qml
我有一个 Scene3D,我可以在其中放置所有实体。我创建一个单独的类并将其命名为 RootEntity。 这种方式更重要的一点是我在类里面使用的orbitController。这使得您可以通过鼠标旋转立方体,为此您需要实体。因此,我使用 Scene3D 和 Entity 而不是 view3d 和模型。
在main.qml中:
import QtQuick 2.12
import QtQuick.Scene3D 2.12
import QtQuick.Window 2.12
import "."
Window {
visible: true
width: 640
height: 480
Scene3D
{
id : scene3d
anchors.fill: parent
focus: true
aspects: ["render", "logic", "input"]
hoverEnabled: true
cameraAspectRatioMode: Scene3D.AutomaticAspectRatio
antialiasing: true
RootEntity
{
id:root
}
}
}
在RootEntity.qml中:
import QtQuick 2.0
import Qt3D.Core 2.12
import Qt3D.Render 2.12
import Qt3D.Extras 2.12
import Qt3D.Input 2.12
import "."
Entity {
id: root
//create camera
Camera {
id: mainCamera
projectionType: CameraLens.PerspectiveProjection
fieldOfView: 45
aspectRatio: 16/9
nearPlane : 0.1
farPlane : 1000.0
position: Qt.vector3d(0.0, 4.49373, -3.78577)
upVector: Qt.vector3d( 0.0, 1.0, 0.0 )
viewCenter: Qt.vector3d(0.0, 0.5, 0.0)
}
//use my class instead of OrbitCameraController
SOrbitCameraController {
id: mainCameraController
camera: mainCamera
}
components: [
RenderSettings {
Viewport {
normalizedRect: Qt.rect(0.0, 0.0, 1.0, 1.0)
RenderSurfaceSelector {
CameraSelector {
id: cameraSelector
camera: mainCamera
FrustumCulling {
ClearBuffers {
buffers: ClearBuffers.AllBuffers
clearColor: "#444449"
NoDraw {}
}
LayerFilter {
filterMode: LayerFilter.DiscardAnyMatchingLayers
layers: [topLayer]
}
LayerFilter {
filterMode: LayerFilter.AcceptAnyMatchingLayers
layers: [topLayer]
ClearBuffers {
buffers: ClearBuffers.DepthBuffer
}
}
}
}
}
}
},
InputSettings {}
,
ScreenRayCaster
{
id:screenRayCaster
onHitsChanged:
{
drawLineMesh(hits)
}
}
]
Layer {
id: topLayer
recursive: true
}
Entity {
id: cubeEntity
components: [
CuboidMesh
{
xExtent: 1
yExtent: 1
zExtent: 1
}
,
Transform {
id: t
translation: Qt.vector3d(0, 0, 0)
}
,
PhongMaterial
{
ambient: "red"
}
]
}
}
在 SOrbitCameraController.qml 中:
import Qt3D.Core 2.0
import Qt3D.Render 2.0
import Qt3D.Input 2.0
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()
}
}
}
最后是我的 main.cpp :
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
{
return -1;
}
return app.exec();
}
关于qt - 如何在 qml 中旋转 3d 立方体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68542807/