Kuesa Car-Scene QML Example
import Qt3D.Core 2.12
import Qt3D.Render 2.12
import Qt3D.Input 2.12
import Qt3D.Logic 2.2
import QtQml 2.12
import QtQuick 2.12 as QQ2
Entity {
id: root
property Camera camera
property real linearSpeed: 8.0
property real lookSpeed: 100.0
QtObject {
id: d
readonly property vector3d firstPersonUp: Qt.vector3d(0, 1, 0)
readonly property bool leftMouseButtonPressed: leftMouseButtonAction.active
readonly property real vx: txAxis.value * linearSpeed;
readonly property real vy: tyAxis.value * linearSpeed;
readonly property real vz: tzAxis.value * linearSpeed;
property real dx: rxAxis.value * lookSpeed
property real dy: ryAxis.value * lookSpeed
property bool actionJustStarted: true
readonly property bool fineMotion: fineMotionAction.active
QQ2.Behavior on dx { QQ2.NumberAnimation { duration: 250; easing.type: QQ2.Easing.OutCubic } }
QQ2.Behavior on dy { QQ2.NumberAnimation { duration: 250; easing.type: QQ2.Easing.OutCubic } }
}
KeyboardDevice {
id: keyboardSourceDevice
}
MouseDevice {
id: mouseSourceDevice
sensitivity: d.fineMotion ? 0.01 : 0.1
}
components: [
LogicalDevice {
id: cameraControlDevice
actions: [
Action {
id: leftMouseButtonAction
ActionInput {
sourceDevice: mouseSourceDevice
buttons: [MouseEvent.LeftButton]
}
},
Action {
id: fineMotionAction
ActionInput {
sourceDevice: keyboardSourceDevice
buttons: [Qt.Key_Shift]
}
}
]
axes: [
Axis {
id: rxAxis
AnalogAxisInput {
sourceDevice: mouseSourceDevice
axis: MouseDevice.X
}
},
Axis {
id: ryAxis
AnalogAxisInput {
sourceDevice: mouseSourceDevice
axis: MouseDevice.Y
}
},
Axis {
id: txAxis
ButtonAxisInput {
sourceDevice: keyboardSourceDevice
buttons: [Qt.Key_Left]
scale: -1.0
}
ButtonAxisInput {
sourceDevice: keyboardSourceDevice
buttons: [Qt.Key_Right]
scale: 1.0
}
},
Axis {
id: tzAxis
ButtonAxisInput {
sourceDevice: keyboardSourceDevice
buttons: [Qt.Key_Up]
scale: 1.0
}
ButtonAxisInput {
sourceDevice: keyboardSourceDevice
buttons: [Qt.Key_Down]
scale: -1.0
}
},
Axis {
id: tyAxis
ButtonAxisInput {
sourceDevice: keyboardSourceDevice
buttons: [Qt.Key_PageUp]
scale: 1.0
}
ButtonAxisInput {
sourceDevice: keyboardSourceDevice
buttons: [Qt.Key_PageDown]
scale: -1.0
}
}
]
},
FrameAction {
property var radius: 0
onTriggered: {
if (!root.enabled)
return
var oldPos = Qt.vector3d(root.camera.position.x,
root.camera.position.y,
root.camera.position.z);
var oldViewCenter = Qt.vector3d(root.camera.viewCenter.x,
root.camera.viewCenter.y,
root.camera.viewCenter.z)
var oldUpVec = Qt.vector3d(root.camera.upVector.x,
root.camera.upVector.y,
root.camera.upVector.z)
if (d.actionJustStarted) {
radius = oldPos.minus(root.camera.viewCenter).length()
d.actionJustStarted = false
}
root.camera.translate(Qt.vector3d(d.vx, d.vy, d.vz).times(dt))
if (d.leftMouseButtonPressed && !d.actionJustStarted) {
root.camera.panAboutViewCenter(-d.dx * dt, d.firstPersonUp)
root.camera.tiltAboutViewCenter(-d.dy * dt)
}
var normalizedViewVect = root.camera.viewVector.normalized()
var normalizedUpVect = root.camera.upVector.normalized()
var viewAngle = Math.acos(normalizedViewVect.dotProduct(d.firstPersonUp)) * 180 / Math.PI;
var upAngle = Math.acos(normalizedUpVect.dotProduct(d.firstPersonUp)) * 180 / Math.PI;
if (viewAngle < 90 || upAngle > 85) {
root.camera.position = oldPos
root.camera.viewCenter = oldViewCenter
root.camera.upVector = oldUpVec
root.camera.panAboutViewCenter(-d.dx * dt, d.firstPersonUp)
}
}
}
]
}