| 
									
										
										
										
											2019-11-15 15:20:31 +02:00
										 |  |  | /**************************************************************************** | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** Copyright (C) 2019 The Qt Company Ltd. | 
					
						
							|  |  |  | ** Contact: https://www.qt.io/licensing/
 | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** This file is part of Qt Creator. | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** Commercial License Usage | 
					
						
							|  |  |  | ** Licensees holding valid commercial Qt licenses may use this file in | 
					
						
							|  |  |  | ** accordance with the commercial license agreement provided with the | 
					
						
							|  |  |  | ** Software or, alternatively, in accordance with the terms contained in | 
					
						
							|  |  |  | ** a written agreement between you and The Qt Company. For licensing terms | 
					
						
							|  |  |  | ** and conditions see https://www.qt.io/terms-conditions. For further
 | 
					
						
							|  |  |  | ** information use the contact form at https://www.qt.io/contact-us.
 | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** GNU General Public License Usage | 
					
						
							|  |  |  | ** Alternatively, this file may be used under the terms of the GNU | 
					
						
							|  |  |  | ** General Public License version 3 as published by the Free Software | 
					
						
							|  |  |  | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT | 
					
						
							|  |  |  | ** included in the packaging of this file. Please review the following | 
					
						
							|  |  |  | ** information to ensure the GNU General Public License requirements will | 
					
						
							|  |  |  | ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
 | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ****************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import QtQuick 2.12 | 
					
						
							| 
									
										
										
										
											2020-02-25 14:37:45 +02:00
										 |  |  | import QtQuick3D 1.15 | 
					
						
							| 
									
										
										
										
											2019-11-15 15:20:31 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | Item { | 
					
						
							|  |  |  |     id: cameraCtrl | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     property Camera camera: null | 
					
						
							| 
									
										
										
										
											2019-11-20 18:01:34 +02:00
										 |  |  |     property View3D view3d: null | 
					
						
							| 
									
										
										
										
											2020-02-10 15:32:57 +02:00
										 |  |  |     property string sceneId | 
					
						
							| 
									
										
										
										
											2019-11-15 15:20:31 +02:00
										 |  |  |     property vector3d _lookAtPoint | 
					
						
							|  |  |  |     property vector3d _pressPoint | 
					
						
							|  |  |  |     property vector3d _prevPoint | 
					
						
							|  |  |  |     property vector3d _startRotation | 
					
						
							|  |  |  |     property vector3d _startPosition | 
					
						
							|  |  |  |     property vector3d _startLookAtPoint | 
					
						
							|  |  |  |     property matrix4x4 _startTransform | 
					
						
							|  |  |  |     property bool _dragging | 
					
						
							|  |  |  |     property int _button | 
					
						
							|  |  |  |     property real _zoomFactor: 1 | 
					
						
							|  |  |  |     property Camera _prevCamera: null | 
					
						
							| 
									
										
										
										
											2020-02-25 14:37:45 +02:00
										 |  |  |     readonly property vector3d _defaultCameraPosition: Qt.vector3d(0, 600, 600) | 
					
						
							|  |  |  |     readonly property vector3d _defaultCameraRotation: Qt.vector3d(-45, 0, 0) | 
					
						
							| 
									
										
										
										
											2020-02-10 15:32:57 +02:00
										 |  |  |     readonly property real _defaultCameraLookAtDistance: _defaultCameraPosition.length() | 
					
						
							| 
									
										
										
										
											2022-01-10 16:40:35 +02:00
										 |  |  |     readonly property real _keyPanAmount: 5 | 
					
						
							| 
									
										
										
										
											2020-09-18 12:56:24 +03:00
										 |  |  |     property bool ignoreToolState: false | 
					
						
							| 
									
										
										
										
											2019-11-15 15:20:31 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-10 15:32:57 +02:00
										 |  |  |     function restoreCameraState(cameraState) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-09-18 12:56:24 +03:00
										 |  |  |         if (!camera || ignoreToolState) | 
					
						
							| 
									
										
										
										
											2020-01-28 10:40:44 +02:00
										 |  |  |             return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-16 17:42:04 +02:00
										 |  |  |         _lookAtPoint = cameraState[0]; | 
					
						
							|  |  |  |         _zoomFactor = cameraState[1]; | 
					
						
							|  |  |  |         camera.position = cameraState[2]; | 
					
						
							|  |  |  |         camera.rotation = cameraState[3]; | 
					
						
							| 
									
										
										
										
											2021-11-15 17:24:23 +02:00
										 |  |  |         _generalHelper.zoomCamera(view3d, camera, 0, _defaultCameraLookAtDistance, _lookAtPoint, | 
					
						
							| 
									
										
										
										
											2020-01-16 17:42:04 +02:00
										 |  |  |                                   _zoomFactor, false); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-10 15:32:57 +02:00
										 |  |  |     function restoreDefaultState() | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (!camera) | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         _lookAtPoint = Qt.vector3d(0, 0, 0); | 
					
						
							|  |  |  |         _zoomFactor = 1; | 
					
						
							|  |  |  |         camera.position = _defaultCameraPosition; | 
					
						
							| 
									
										
										
										
											2020-02-25 14:37:45 +02:00
										 |  |  |         camera.eulerRotation = _defaultCameraRotation; | 
					
						
							| 
									
										
										
										
											2021-11-15 17:24:23 +02:00
										 |  |  |         _generalHelper.zoomCamera(view3d, camera, 0, _defaultCameraLookAtDistance, _lookAtPoint, | 
					
						
							| 
									
										
										
										
											2020-02-10 15:32:57 +02:00
										 |  |  |                                   _zoomFactor, false); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function storeCameraState(delay) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-09-18 12:56:24 +03:00
										 |  |  |         if (!camera || ignoreToolState) | 
					
						
							| 
									
										
										
										
											2020-01-28 10:40:44 +02:00
										 |  |  |             return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-16 17:42:04 +02:00
										 |  |  |         var cameraState = []; | 
					
						
							|  |  |  |         cameraState[0] = _lookAtPoint; | 
					
						
							|  |  |  |         cameraState[1] = _zoomFactor; | 
					
						
							|  |  |  |         cameraState[2] = camera.position; | 
					
						
							|  |  |  |         cameraState[3] = camera.rotation; | 
					
						
							| 
									
										
										
										
											2020-02-10 15:32:57 +02:00
										 |  |  |         _generalHelper.storeToolState(sceneId, "editCamState", cameraState, delay); | 
					
						
							| 
									
										
										
										
											2020-01-16 17:42:04 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-01 16:24:02 +03:00
										 |  |  |     function focusObject(targetNodes, rotation, updateZoom, closeUp) | 
					
						
							| 
									
										
										
										
											2019-11-20 18:01:34 +02:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-01-28 10:40:44 +02:00
										 |  |  |         if (!camera) | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-01 16:24:02 +03:00
										 |  |  |         // targetNodes could be a list of nodes or a single node
 | 
					
						
							|  |  |  |         var nodes = []; | 
					
						
							|  |  |  |         if (targetNodes instanceof Node) | 
					
						
							|  |  |  |             nodes.push(targetNodes); | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             nodes = targetNodes | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-25 14:37:45 +02:00
										 |  |  |         camera.eulerRotation = rotation; | 
					
						
							| 
									
										
										
										
											2021-07-01 16:24:02 +03:00
										 |  |  |         var newLookAtAndZoom = _generalHelper.focusNodesToCamera( | 
					
						
							|  |  |  |                     camera, _defaultCameraLookAtDistance, nodes, view3d, _zoomFactor, | 
					
						
							| 
									
										
										
										
											2020-04-23 15:40:41 +03:00
										 |  |  |                     updateZoom, closeUp); | 
					
						
							| 
									
										
										
										
											2019-11-20 18:01:34 +02:00
										 |  |  |         _lookAtPoint = newLookAtAndZoom.toVector3d(); | 
					
						
							|  |  |  |         _zoomFactor = newLookAtAndZoom.w; | 
					
						
							| 
									
										
										
										
											2020-01-16 17:42:04 +02:00
										 |  |  |         storeCameraState(0); | 
					
						
							| 
									
										
										
										
											2019-11-20 18:01:34 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-15 15:20:31 +02:00
										 |  |  |     function zoomRelative(distance) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-01-28 10:40:44 +02:00
										 |  |  |         if (!camera) | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-15 17:24:23 +02:00
										 |  |  |         _zoomFactor = _generalHelper.zoomCamera(view3d, camera, distance, _defaultCameraLookAtDistance, | 
					
						
							| 
									
										
										
										
											2019-11-15 15:20:31 +02:00
										 |  |  |                                                 _lookAtPoint, _zoomFactor, true); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     onCameraChanged: { | 
					
						
							| 
									
										
										
										
											2020-01-28 10:40:44 +02:00
										 |  |  |         if (camera && _prevCamera) { | 
					
						
							| 
									
										
										
										
											2019-11-15 15:20:31 +02:00
										 |  |  |             // Reset zoom on previous camera to ensure it's properties are good to copy to new cam
 | 
					
						
							| 
									
										
										
										
											2021-11-15 17:24:23 +02:00
										 |  |  |             _generalHelper.zoomCamera(view3d, _prevCamera, 0, _defaultCameraLookAtDistance, _lookAtPoint, | 
					
						
							| 
									
										
										
										
											2019-11-15 15:20:31 +02:00
										 |  |  |                                       1, false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             camera.position = _prevCamera.position; | 
					
						
							|  |  |  |             camera.rotation = _prevCamera.rotation; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // Apply correct zoom to new camera
 | 
					
						
							| 
									
										
										
										
											2021-11-15 17:24:23 +02:00
										 |  |  |             _generalHelper.zoomCamera(view3d, camera, 0, _defaultCameraLookAtDistance, _lookAtPoint, | 
					
						
							| 
									
										
										
										
											2019-11-15 15:20:31 +02:00
										 |  |  |                                       _zoomFactor, false); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         _prevCamera = camera; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     MouseArea { | 
					
						
							|  |  |  |         id: mouseHandler | 
					
						
							|  |  |  |         acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton | 
					
						
							|  |  |  |         hoverEnabled: false | 
					
						
							|  |  |  |         anchors.fill: parent | 
					
						
							| 
									
										
										
										
											2021-06-08 16:13:18 +03:00
										 |  |  |         onPositionChanged: (mouse)=> { | 
					
						
							| 
									
										
										
										
											2020-01-28 10:40:44 +02:00
										 |  |  |             if (cameraCtrl.camera && mouse.modifiers === Qt.AltModifier && cameraCtrl._dragging) { | 
					
						
							| 
									
										
										
										
											2019-11-15 15:20:31 +02:00
										 |  |  |                 var currentPoint = Qt.vector3d(mouse.x, mouse.y, 0); | 
					
						
							|  |  |  |                 if (cameraCtrl._button == Qt.LeftButton) { | 
					
						
							|  |  |  |                     _generalHelper.orbitCamera(cameraCtrl.camera, cameraCtrl._startRotation, | 
					
						
							|  |  |  |                                                cameraCtrl._lookAtPoint, cameraCtrl._pressPoint, | 
					
						
							|  |  |  |                                                currentPoint); | 
					
						
							|  |  |  |                 } else if (cameraCtrl._button == Qt.MiddleButton) { | 
					
						
							|  |  |  |                     cameraCtrl._lookAtPoint = _generalHelper.panCamera( | 
					
						
							|  |  |  |                                 cameraCtrl.camera, cameraCtrl._startTransform, | 
					
						
							|  |  |  |                                 cameraCtrl._startPosition, cameraCtrl._startLookAtPoint, | 
					
						
							|  |  |  |                                 cameraCtrl._pressPoint, currentPoint, _zoomFactor); | 
					
						
							|  |  |  |                 } else if (cameraCtrl._button == Qt.RightButton) { | 
					
						
							|  |  |  |                     cameraCtrl.zoomRelative(currentPoint.y - cameraCtrl._prevPoint.y) | 
					
						
							|  |  |  |                     cameraCtrl._prevPoint = currentPoint; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-06-08 16:13:18 +03:00
										 |  |  |         onPressed: (mouse)=> { | 
					
						
							| 
									
										
										
										
											2020-01-28 10:40:44 +02:00
										 |  |  |             if (cameraCtrl.camera && mouse.modifiers === Qt.AltModifier) { | 
					
						
							| 
									
										
										
										
											2019-11-15 15:20:31 +02:00
										 |  |  |                 cameraCtrl._dragging = true; | 
					
						
							| 
									
										
										
										
											2020-02-25 14:37:45 +02:00
										 |  |  |                 cameraCtrl._startRotation = cameraCtrl.camera.eulerRotation; | 
					
						
							| 
									
										
										
										
											2019-11-15 15:20:31 +02:00
										 |  |  |                 cameraCtrl._startPosition = cameraCtrl.camera.position; | 
					
						
							|  |  |  |                 cameraCtrl._startLookAtPoint = _lookAtPoint; | 
					
						
							|  |  |  |                 cameraCtrl._pressPoint = Qt.vector3d(mouse.x, mouse.y, 0); | 
					
						
							|  |  |  |                 cameraCtrl._prevPoint = cameraCtrl._pressPoint; | 
					
						
							|  |  |  |                 cameraCtrl._button = mouse.button; | 
					
						
							|  |  |  |                 cameraCtrl._startTransform = cameraCtrl.camera.sceneTransform; | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 mouse.accepted = false; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-16 17:42:04 +02:00
										 |  |  |         function handleRelease() { | 
					
						
							|  |  |  |             cameraCtrl._dragging = false; | 
					
						
							|  |  |  |             cameraCtrl.storeCameraState(0); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         onReleased: handleRelease() | 
					
						
							|  |  |  |         onCanceled: handleRelease() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-08 16:13:18 +03:00
										 |  |  |         onWheel: (wheel)=> { | 
					
						
							| 
									
										
										
										
											2020-01-28 10:40:44 +02:00
										 |  |  |             if (cameraCtrl.camera) { | 
					
						
							| 
									
										
										
										
											2020-01-31 11:41:27 +02:00
										 |  |  |                 // Empirically determined divisor for nice zoom
 | 
					
						
							| 
									
										
										
										
											2020-01-28 10:40:44 +02:00
										 |  |  |                 cameraCtrl.zoomRelative(wheel.angleDelta.y / -40); | 
					
						
							|  |  |  |                 cameraCtrl.storeCameraState(500); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-11-15 15:20:31 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-01-10 16:40:35 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Keys.onPressed: { | 
					
						
							|  |  |  |         var pressPoint = Qt.vector3d(view3d.width / 2, view3d.height / 2, 0); | 
					
						
							|  |  |  |         var currentPoint; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         switch (event.key) { | 
					
						
							|  |  |  |         case Qt.Key_Left: | 
					
						
							|  |  |  |             currentPoint = pressPoint.plus(Qt.vector3d(_keyPanAmount, 0, 0)); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case Qt.Key_Right: | 
					
						
							|  |  |  |             currentPoint = pressPoint.plus(Qt.vector3d(-_keyPanAmount, 0, 0)); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case Qt.Key_Up: | 
					
						
							|  |  |  |             currentPoint = pressPoint.plus(Qt.vector3d(0, _keyPanAmount, 0)); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case Qt.Key_Down: | 
					
						
							|  |  |  |             currentPoint = pressPoint.plus(Qt.vector3d(0, -_keyPanAmount, 0)); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (currentPoint) { | 
					
						
							|  |  |  |             _lookAtPoint = _generalHelper.panCamera( | 
					
						
							|  |  |  |                         camera, cameraCtrl.camera.sceneTransform, | 
					
						
							|  |  |  |                         cameraCtrl.camera.position, _lookAtPoint, | 
					
						
							|  |  |  |                         pressPoint, currentPoint, _zoomFactor); | 
					
						
							|  |  |  |             event.accepted = true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-11-15 15:20:31 +02:00
										 |  |  | } |