Kuesa Music Box QML Example
import Qt3D.Core 2.12
import Qt3D.Render 2.12
import Qt3D.Input 2.12
import Qt3D.Logic 2.12
import QtQml 2.11
import QtQuick 2.11 as QQ2
Entity {
id: root
property Camera camera
property real lookSpeed: 30000.0
property real mouseWheelZoomSpeed: 0.001
property real zoomSpeed: 0.01
property real panSpeed: 0.00125
property real minCameraToViewCenterDistance: 2.
property real maxCameraToViewCenterDistance: 20.
QtObject {
id: d
readonly property vector3d firstPersonUp: Qt.vector3d(0, 1, 0)
readonly property bool leftMouseButtonPressed: leftMouseButtonAction.active || (Qt.platform.os == "osx" && rightMouseButtonAction.active && metaAction.active)
property real dx: rxAxis.value * lookSpeed
property real dy: ryAxis.value * lookSpeed
property real dz: rzAxis.value * lookSpeed
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 } }
QQ2.Behavior on dz { QQ2.NumberAnimation { duration: 250; easing.type: QQ2.Easing.OutCubic } }
}
function rotateCamera(dx, dy) {
camera.panAboutViewCenter(-dx, d.firstPersonUp)
var tiltCamera = false;
if (dy > 0) {
tiltCamera = true;
} else {
var vv = camera.viewVector.normalized();
var uv = camera.upVector.normalized();
var a = vv.crossProduct(uv);
var b = vv.crossProduct(a);
if (Math.abs(b.y) > 0.2)
tiltCamera = true;
}
var cameraToCenter = camera.position.minus(camera.viewCenter).length()
if (tiltCamera)
camera.tiltAboutViewCenter(-dy);
if (camera.position.y < 0) {
camera.position.y = 0;
var v = camera.position.minus(camera.viewCenter).normalized()
camera.position = camera.viewCenter.plus(v.times(cameraToCenter))
}
camera.upVector = d.firstPersonUp
}
function zoomCamera(dz) {
var cameraToCenter = camera.position.minus(camera.viewCenter)
var distance = cameraToCenter.length()
distance -= distance* dz
distance = Math.min(Math.max(distance, minCameraToViewCenterDistance), maxCameraToViewCenterDistance)
camera.position = camera.viewCenter.plus(cameraToCenter.normalized().times(distance))
}
KeyboardDevice {
id: keyboardSourceDevice
}
KeyboardHandler {
sourceDevice: keyboardSourceDevice
focus: true
}
MouseDevice {
id: mouseSourceDevice
sensitivity: d.fineMotion ? 0.0001 : 0.001
}
components: [
LogicalDevice {
id: cameraControlDevice
actions: [
Action {
id: leftMouseButtonAction
ActionInput {
sourceDevice: mouseSourceDevice
buttons: [MouseEvent.LeftButton]
}
},
Action {
id: middleMouseButtonAction
ActionInput {
sourceDevice: mouseSourceDevice
buttons: [MouseEvent.MiddleButton]
}
},
Action {
id: rightMouseButtonAction
ActionInput {
sourceDevice: mouseSourceDevice
buttons: [MouseEvent.RightButton]
}
},
Action {
id: shiftAction
ActionInput {
sourceDevice: keyboardSourceDevice
buttons: [Qt.Key_Shift]
}
},
Action {
id: ctrlAction
ActionInput {
sourceDevice: keyboardSourceDevice
buttons: [Qt.Key_Control]
}
},
Action {
id: metaAction
enabled: Qt.platform.os == "osx"
ActionInput {
sourceDevice: keyboardSourceDevice
buttons: [Qt.Key_Meta]
}
},
Action {
id: altAction
ActionInput {
sourceDevice: keyboardSourceDevice
buttons: [Qt.Key_Alt]
}
}
]
axes: [
Axis {
id: rxAxis
AnalogAxisInput {
sourceDevice: mouseSourceDevice
axis: MouseDevice.X
}
},
Axis {
id: ryAxis
AnalogAxisInput {
sourceDevice: mouseSourceDevice
axis: MouseDevice.Y
}
},
Axis {
id: rzAxis
AnalogAxisInput {
sourceDevice: mouseSourceDevice
axis: MouseDevice.WheelY
}
}
]
},
FrameAction {
onTriggered: {
if (!root.enabled)
return
zoomCamera(d.dz * mouseWheelZoomSpeed * dt)
if (d.leftMouseButtonPressed)
rotateCamera(d.dx * dt, d.dy * dt);
}
}
]
}