| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- // Copyright (C) 2022 The Qt Company Ltd.
- // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
- import QtQuick
- import QtQuick3D
- Item {
- id: root
- required property Node origin
- required property Camera camera
- property real xSpeed: 0.1
- property real ySpeed: 0.1
- property bool xInvert: false
- property bool yInvert: true
- property bool mouseEnabled: true
- property bool panEnabled: true
- property bool automaticClipping: true
- property alias acceptedButtons: dragHandler.acceptedButtons
- readonly property bool inputsNeedProcessing: status.useMouse || status.isPanning
- implicitWidth: parent.width
- implicitHeight: parent.height
- Connections {
- enabled: root.automaticClipping
- target: root.camera
- function onZChanged() {
- // Adjust near/far values based on distance
- let distance = root.camera.z
- if (distance < 1) {
- root.camera.clipNear = 0.01
- root.camera.clipFar = 100
- if (root.camera.z === 0) {
- console.warn("camera z set to 0, setting it to near clip")
- root.camera.z = root.camera.clipNear
- }
- } else if (distance < 100) {
- root.camera.clipNear = 0.1
- root.camera.clipFar = 1000
- } else {
- root.camera.clipNear = 1
- root.camera.clipFar = 10000
- }
- }
- }
- DragHandler {
- id: dragHandler
- target: null
- enabled: root.mouseEnabled
- acceptedModifiers: Qt.NoModifier
- onCentroidChanged: {
- root.mouseMoved(Qt.vector2d(centroid.position.x, centroid.position.y), false);
- }
- onActiveChanged: {
- if (active)
- root.mousePressed(Qt.vector2d(centroid.position.x, centroid.position.y));
- else
- root.mouseReleased(Qt.vector2d(centroid.position.x, centroid.position.y));
- }
- }
- DragHandler {
- id: ctrlDragHandler
- target: null
- enabled: root.mouseEnabled && root.panEnabled
- acceptedButtons: root.acceptedButtons
- acceptedModifiers: Qt.ControlModifier
- onCentroidChanged: {
- root.panEvent(Qt.vector2d(centroid.position.x, centroid.position.y));
- }
- onActiveChanged: {
- if (active)
- root.startPan(Qt.vector2d(centroid.position.x, centroid.position.y));
- else
- root.endPan();
- }
- }
- PinchHandler {
- id: pinchHandler
- target: null
- enabled: root.mouseEnabled
- onTranslationChanged: (delta) => {
- if (!root.panEnabled)
- return;
- delta.x = -(delta.x / root.width) * root.camera.z;
- delta.y = (delta.y / root.height) * root.camera.z;
- let movement = Qt.vector3d(0, 0, 0)
- // X Movement
- let xDirection = root.origin.right
- movement = movement.plus(Qt.vector3d(xDirection.x * delta.x,
- xDirection.y * delta.x,
- xDirection.z * delta.x));
- // Y Movement
- let yDirection = root.origin.up
- movement = movement.plus(Qt.vector3d(yDirection.x * delta.y,
- yDirection.y * delta.y,
- yDirection.z * delta.y));
- root.origin.position = root.origin.position.plus(movement)
- }
- onScaleChanged: (delta) => {
- root.camera.z = root.camera.z * (1 / delta)
- }
- }
- TapHandler {
- acceptedButtons: root.acceptedButtons
- onTapped: root.forceActiveFocus() // qmllint disable signal-handler-parameters
- }
- WheelHandler {
- id: wheelHandler
- orientation: Qt.Vertical
- target: null
- enabled: root.mouseEnabled
- acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
- onWheel: event => {
- let delta = -event.angleDelta.y * 0.01;
- root.camera.z += root.camera.z * 0.1 * delta
- }
- }
- function mousePressed(newPos) {
- root.forceActiveFocus()
- status.currentPos = newPos
- status.lastPos = newPos
- status.useMouse = true;
- }
- function mouseReleased(newPos) {
- status.useMouse = false;
- }
- function mouseMoved(newPos: vector2d) {
- status.currentPos = newPos;
- }
- function startPan(pos: vector2d) {
- status.isPanning = true;
- status.currentPanPos = pos;
- status.lastPanPos = pos;
- }
- function endPan() {
- status.isPanning = false;
- }
- function panEvent(newPos: vector2d) {
- status.currentPanPos = newPos;
- }
- FrameAnimation {
- id: updateTimer
- running: root.inputsNeedProcessing
- onTriggered: status.processInput(frameTime * 100)
- }
- QtObject {
- id: status
- property bool useMouse: false
- property bool isPanning: false
- property vector2d lastPos: Qt.vector2d(0, 0)
- property vector2d lastPanPos: Qt.vector2d(0, 0)
- property vector2d currentPos: Qt.vector2d(0, 0)
- property vector2d currentPanPos: Qt.vector2d(0, 0)
- function negate(vector) {
- return Qt.vector3d(-vector.x, -vector.y, -vector.z)
- }
- function processInput(frameDelta) {
- if (useMouse) {
- // Get the delta
- var rotationVector = root.origin.eulerRotation;
- var delta = Qt.vector2d(lastPos.x - currentPos.x,
- lastPos.y - currentPos.y);
- // rotate x
- var rotateX = delta.x * root.xSpeed * frameDelta
- if (root.xInvert)
- rotateX = -rotateX;
- rotationVector.y += rotateX;
- // rotate y
- var rotateY = delta.y * -root.ySpeed * frameDelta
- if (root.yInvert)
- rotateY = -rotateY;
- rotationVector.x += rotateY;
- root.origin.setEulerRotation(rotationVector);
- lastPos = currentPos;
- }
- if (isPanning) {
- let delta = currentPanPos.minus(lastPanPos);
- delta.x = -delta.x
- delta.x = (delta.x / root.width) * root.camera.z * frameDelta
- delta.y = (delta.y / root.height) * root.camera.z * frameDelta
- let velocity = Qt.vector3d(0, 0, 0)
- // X Movement
- let xDirection = root.origin.right
- velocity = velocity.plus(Qt.vector3d(xDirection.x * delta.x,
- xDirection.y * delta.x,
- xDirection.z * delta.x));
- // Y Movement
- let yDirection = root.origin.up
- velocity = velocity.plus(Qt.vector3d(yDirection.x * delta.y,
- yDirection.y * delta.y,
- yDirection.z * delta.y));
- root.origin.position = root.origin.position.plus(velocity)
- lastPanPos = currentPanPos
- }
- }
- }
- }
|