forked from qt-creator/qt-creator
QmlPuppet: Add separate set of qml files for Qt6 for 3D editor
Import QtQuick3D 1.15 no longer works in Qt 6.2, so provide a separate set of qml files for each major Qt version. Fixes: QDS-4642 Change-Id: I3e17fb248f71f87fb9a40dcad3c03e037cafb0f4 Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: Samuel Ghinet <samuel.ghinet@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
<RCC>
|
||||
<qresource prefix="/qtquickplugin">
|
||||
<file>mockfiles/meshes/arrow.mesh</file>
|
||||
<file>mockfiles/meshes/scalerod.mesh</file>
|
||||
<file>mockfiles/meshes/ring.mesh</file>
|
||||
<file>mockfiles/meshes/ringselect.mesh</file>
|
||||
<file>mockfiles/meshes/axishelper.mesh</file>
|
||||
<file>mockfiles/images/editor_camera.png</file>
|
||||
<file>mockfiles/images/editor_camera@2x.png</file>
|
||||
<file>mockfiles/images/area.png</file>
|
||||
<file>mockfiles/images/area@2x.png</file>
|
||||
<file>mockfiles/images/directional.png</file>
|
||||
<file>mockfiles/images/directional@2x.png</file>
|
||||
<file>mockfiles/images/point.png</file>
|
||||
<file>mockfiles/images/point@2x.png</file>
|
||||
<file>mockfiles/images/spot.png</file>
|
||||
<file>mockfiles/images/spot@2x.png</file>
|
||||
<file>mockfiles/qt5/AdjustableArrow.qml</file>
|
||||
<file>mockfiles/qt5/AreaLightHandle.qml</file>
|
||||
<file>mockfiles/qt5/Arrow.qml</file>
|
||||
<file>mockfiles/qt5/AutoScaleHelper.qml</file>
|
||||
<file>mockfiles/qt5/AxisHelper.qml</file>
|
||||
<file>mockfiles/qt5/AxisHelperArm.qml</file>
|
||||
<file>mockfiles/qt5/CameraFrustum.qml</file>
|
||||
<file>mockfiles/qt5/CameraGizmo.qml</file>
|
||||
<file>mockfiles/qt5/DirectionalDraggable.qml</file>
|
||||
<file>mockfiles/qt5/EditCameraController.qml</file>
|
||||
<file>mockfiles/qt5/EditView3D.qml</file>
|
||||
<file>mockfiles/qt5/FadeHandle.qml</file>
|
||||
<file>mockfiles/qt5/HelperGrid.qml</file>
|
||||
<file>mockfiles/qt5/IconGizmo.qml</file>
|
||||
<file>mockfiles/qt5/IconRenderer3D.qml</file>
|
||||
<file>mockfiles/qt5/LightGizmo.qml</file>
|
||||
<file>mockfiles/qt5/LightIconGizmo.qml</file>
|
||||
<file>mockfiles/qt5/LightModel.qml</file>
|
||||
<file>mockfiles/qt5/Line3D.qml</file>
|
||||
<file>mockfiles/qt5/MaterialNodeView.qml</file>
|
||||
<file>mockfiles/qt5/ModelNode2DImageView.qml</file>
|
||||
<file>mockfiles/qt5/ModelNode3DImageView.qml</file>
|
||||
<file>mockfiles/qt5/ModelNodeView.qml</file>
|
||||
<file>mockfiles/qt5/MoveGizmo.qml</file>
|
||||
<file>mockfiles/qt5/NodeNodeView.qml</file>
|
||||
<file>mockfiles/qt5/Overlay2D.qml</file>
|
||||
<file>mockfiles/qt5/PlanarDraggable.qml</file>
|
||||
<file>mockfiles/qt5/PlanarMoveHandle.qml</file>
|
||||
<file>mockfiles/qt5/PlanarScaleHandle.qml</file>
|
||||
<file>mockfiles/qt5/RotateGizmo.qml</file>
|
||||
<file>mockfiles/qt5/RotateRing.qml</file>
|
||||
<file>mockfiles/qt5/ScaleGizmo.qml</file>
|
||||
<file>mockfiles/qt5/ScaleRod.qml</file>
|
||||
<file>mockfiles/qt5/SceneView3D.qml</file>
|
||||
<file>mockfiles/qt5/SelectionBox.qml</file>
|
||||
<file>mockfiles/qt5/SpotLightHandle.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -0,0 +1,55 @@
|
||||
<RCC>
|
||||
<qresource prefix="/qtquickplugin">
|
||||
<file>mockfiles/meshes/arrow.mesh</file>
|
||||
<file>mockfiles/meshes/scalerod.mesh</file>
|
||||
<file>mockfiles/meshes/ring.mesh</file>
|
||||
<file>mockfiles/meshes/ringselect.mesh</file>
|
||||
<file>mockfiles/meshes/axishelper.mesh</file>
|
||||
<file>mockfiles/images/editor_camera.png</file>
|
||||
<file>mockfiles/images/editor_camera@2x.png</file>
|
||||
<file>mockfiles/images/area.png</file>
|
||||
<file>mockfiles/images/area@2x.png</file>
|
||||
<file>mockfiles/images/directional.png</file>
|
||||
<file>mockfiles/images/directional@2x.png</file>
|
||||
<file>mockfiles/images/point.png</file>
|
||||
<file>mockfiles/images/point@2x.png</file>
|
||||
<file>mockfiles/images/spot.png</file>
|
||||
<file>mockfiles/images/spot@2x.png</file>
|
||||
<file>mockfiles/qt6/AdjustableArrow.qml</file>
|
||||
<file>mockfiles/qt6/AreaLightHandle.qml</file>
|
||||
<file>mockfiles/qt6/Arrow.qml</file>
|
||||
<file>mockfiles/qt6/AutoScaleHelper.qml</file>
|
||||
<file>mockfiles/qt6/AxisHelper.qml</file>
|
||||
<file>mockfiles/qt6/AxisHelperArm.qml</file>
|
||||
<file>mockfiles/qt6/CameraFrustum.qml</file>
|
||||
<file>mockfiles/qt6/CameraGizmo.qml</file>
|
||||
<file>mockfiles/qt6/DirectionalDraggable.qml</file>
|
||||
<file>mockfiles/qt6/EditCameraController.qml</file>
|
||||
<file>mockfiles/qt6/EditView3D.qml</file>
|
||||
<file>mockfiles/qt6/FadeHandle.qml</file>
|
||||
<file>mockfiles/qt6/HelperGrid.qml</file>
|
||||
<file>mockfiles/qt6/IconGizmo.qml</file>
|
||||
<file>mockfiles/qt6/IconRenderer3D.qml</file>
|
||||
<file>mockfiles/qt6/LightGizmo.qml</file>
|
||||
<file>mockfiles/qt6/LightIconGizmo.qml</file>
|
||||
<file>mockfiles/qt6/LightModel.qml</file>
|
||||
<file>mockfiles/qt6/Line3D.qml</file>
|
||||
<file>mockfiles/qt6/MaterialNodeView.qml</file>
|
||||
<file>mockfiles/qt6/ModelNode2DImageView.qml</file>
|
||||
<file>mockfiles/qt6/ModelNode3DImageView.qml</file>
|
||||
<file>mockfiles/qt6/ModelNodeView.qml</file>
|
||||
<file>mockfiles/qt6/MoveGizmo.qml</file>
|
||||
<file>mockfiles/qt6/NodeNodeView.qml</file>
|
||||
<file>mockfiles/qt6/Overlay2D.qml</file>
|
||||
<file>mockfiles/qt6/PlanarDraggable.qml</file>
|
||||
<file>mockfiles/qt6/PlanarMoveHandle.qml</file>
|
||||
<file>mockfiles/qt6/PlanarScaleHandle.qml</file>
|
||||
<file>mockfiles/qt6/RotateGizmo.qml</file>
|
||||
<file>mockfiles/qt6/RotateRing.qml</file>
|
||||
<file>mockfiles/qt6/ScaleGizmo.qml</file>
|
||||
<file>mockfiles/qt6/ScaleRod.qml</file>
|
||||
<file>mockfiles/qt6/SceneView3D.qml</file>
|
||||
<file>mockfiles/qt6/SelectionBox.qml</file>
|
||||
<file>mockfiles/qt6/SpotLightHandle.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
+1
-1
@@ -28,7 +28,7 @@ import QtQuick3D 1.15
|
||||
|
||||
DirectionalDraggable {
|
||||
id: arrow
|
||||
source: "meshes/arrow.mesh"
|
||||
source: "../meshes/arrow.mesh"
|
||||
|
||||
signal positionCommit()
|
||||
signal positionMove()
|
||||
+1
-1
@@ -42,7 +42,7 @@ Node {
|
||||
property bool hovering: false
|
||||
property vector3d cameraRotation: armRoot.camRotPos
|
||||
|
||||
source: "meshes/axishelper.mesh"
|
||||
source: "../meshes/axishelper.mesh"
|
||||
materials: DefaultMaterial {
|
||||
id: posMat
|
||||
diffuseColor: posModel.hovering ? armRoot.hoverColor : armRoot.color
|
||||
+2
-2
@@ -49,12 +49,12 @@ Model {
|
||||
signal rotateCommit()
|
||||
signal rotateChange()
|
||||
|
||||
source: "meshes/ring.mesh"
|
||||
source: "../meshes/ring.mesh"
|
||||
|
||||
Model {
|
||||
id: pickModel
|
||||
objectName: "PickModel for " + rotateRing.objectName
|
||||
source: "meshes/ringselect.mesh"
|
||||
source: "../meshes/ringselect.mesh"
|
||||
pickable: true
|
||||
}
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ import MouseArea3D 1.0
|
||||
|
||||
DirectionalDraggable {
|
||||
id: scaleRod
|
||||
source: "meshes/scalerod.mesh"
|
||||
source: "../meshes/scalerod.mesh"
|
||||
|
||||
property vector3d axis
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
import LineGeometry 1.0
|
||||
|
||||
DirectionalDraggable {
|
||||
id: arrowRoot
|
||||
|
||||
Model {
|
||||
geometry: LineGeometry {
|
||||
id: lineGeometry
|
||||
name: "Edit 3D ScalableArrow"
|
||||
startPos: Qt.vector3d(0, 0, 0)
|
||||
endPos: Qt.vector3d(0, 1, 0)
|
||||
}
|
||||
scale: Qt.vector3d(1, arrowRoot.length, 1)
|
||||
materials: [ arrowRoot.material ]
|
||||
}
|
||||
|
||||
Model {
|
||||
id: arrowHead
|
||||
source: "#Cone"
|
||||
materials: [ arrowRoot.material ]
|
||||
y: arrowRoot.length - 3
|
||||
scale: Qt.vector3d(0.02, 0.035, 0.02)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
|
||||
DirectionalDraggable {
|
||||
id: handleRoot
|
||||
|
||||
property string currentLabel
|
||||
property point currentMousePos
|
||||
property string propName
|
||||
property real propValue: 0
|
||||
property real newValue: 0
|
||||
property real baseScale: 5
|
||||
|
||||
scale: autoScaler.getScale(Qt.vector3d(baseScale, baseScale, baseScale))
|
||||
length: 3
|
||||
offset: -1.5
|
||||
|
||||
Model {
|
||||
id: handle
|
||||
source: "#Sphere"
|
||||
materials: [ handleRoot.material ]
|
||||
scale: Qt.vector3d(0.02, 0.02, 0.02)
|
||||
}
|
||||
|
||||
AutoScaleHelper {
|
||||
id: autoScaler
|
||||
active: handleRoot.active
|
||||
view3D: handleRoot.view3D
|
||||
}
|
||||
|
||||
property real _startValue
|
||||
property real _startScale
|
||||
|
||||
signal valueCommit()
|
||||
signal valueChange()
|
||||
|
||||
function updateValue(relativeDistance, screenPos)
|
||||
{
|
||||
handleRoot.newValue = Math.round(Math.min(999999, Math.max(0, _startValue + (relativeDistance * _startScale))));
|
||||
var l = Qt.locale();
|
||||
handleRoot.currentLabel = propName + qsTr(": ") + Number(newValue).toLocaleString(l, 'f', 0);
|
||||
handleRoot.currentMousePos = screenPos;
|
||||
}
|
||||
|
||||
onPressed: (mouseArea, screenPos)=> {
|
||||
_startScale = autoScaler.relativeScale * baseScale;
|
||||
_startValue = propValue;
|
||||
updateValue(0, screenPos);
|
||||
}
|
||||
|
||||
onDragged: (mouseArea, sceneRelativeDistance, relativeDistance, screenPos)=> {
|
||||
updateValue(relativeDistance, screenPos);
|
||||
handleRoot.valueChange();
|
||||
}
|
||||
|
||||
onReleased: (mouseArea, sceneRelativeDistance, relativeDistance, screenPos)=> {
|
||||
updateValue(relativeDistance, screenPos);
|
||||
handleRoot.valueCommit();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
|
||||
DirectionalDraggable {
|
||||
id: arrow
|
||||
source: "../meshes/arrow.mesh"
|
||||
|
||||
signal positionCommit()
|
||||
signal positionMove()
|
||||
|
||||
function localPos(sceneRelativeDistance)
|
||||
{
|
||||
var newScenePos = Qt.vector3d(
|
||||
_targetStartPos.x + sceneRelativeDistance.x,
|
||||
_targetStartPos.y + sceneRelativeDistance.y,
|
||||
_targetStartPos.z + sceneRelativeDistance.z);
|
||||
return targetNode.parent ? targetNode.parent.mapPositionFromScene(newScenePos) : newScenePos;
|
||||
}
|
||||
|
||||
onPressed: {
|
||||
if (targetNode == multiSelectionNode)
|
||||
_generalHelper.restartMultiSelection();
|
||||
}
|
||||
|
||||
onDragged: (mouseArea, sceneRelativeDistance)=> {
|
||||
targetNode.position = localPos(sceneRelativeDistance);
|
||||
if (targetNode == multiSelectionNode)
|
||||
_generalHelper.moveMultiSelection(false);
|
||||
positionMove();
|
||||
}
|
||||
|
||||
onReleased: (mouseArea, sceneRelativeDistance)=> {
|
||||
targetNode.position = localPos(sceneRelativeDistance);
|
||||
if (targetNode == multiSelectionNode)
|
||||
_generalHelper.moveMultiSelection(true);
|
||||
positionCommit();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
import MouseArea3D 1.0
|
||||
|
||||
Node {
|
||||
id: overlayNode
|
||||
|
||||
property View3D view3D
|
||||
property Camera camera: view3D.camera
|
||||
property bool active: true
|
||||
|
||||
// Read-only
|
||||
property real relativeScale: 1
|
||||
|
||||
onActiveChanged: updateScale()
|
||||
onSceneTransformChanged: updateScale()
|
||||
// Trigger delayed update on camera change to ensure camera values are correct
|
||||
onCameraChanged: _generalHelper.requestOverlayUpdate();
|
||||
|
||||
Connections {
|
||||
target: camera
|
||||
function onSceneTransformChanged() { updateScale() }
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: _generalHelper
|
||||
function onOverlayUpdateNeeded() { updateScale() }
|
||||
}
|
||||
|
||||
function getScale(baseScale)
|
||||
{
|
||||
return Qt.vector3d(baseScale.x * relativeScale, baseScale.y * relativeScale,
|
||||
baseScale.z * relativeScale);
|
||||
}
|
||||
|
||||
function updateScale()
|
||||
{
|
||||
if (active)
|
||||
relativeScale = helper.getRelativeScale(overlayNode);
|
||||
else
|
||||
relativeScale = 1;
|
||||
}
|
||||
|
||||
MouseArea3D {
|
||||
id: helper
|
||||
active: false
|
||||
view3D: overlayNode.view3D
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
|
||||
View3D {
|
||||
id: axisHelperView
|
||||
|
||||
property var editCameraCtrl
|
||||
property Node selectedNode
|
||||
|
||||
camera: axisHelperCamera
|
||||
|
||||
Node {
|
||||
OrthographicCamera {
|
||||
id: axisHelperCamera
|
||||
rotation: editCameraCtrl.camera ? editCameraCtrl.camera.rotation : Qt.quaternion(1, 0, 0, 0)
|
||||
position: editCameraCtrl.camera ? editCameraCtrl.camera.position.minus(editCameraCtrl._lookAtPoint)
|
||||
.normalized().times(600) : Qt.vector3d(0, 0, 0)
|
||||
}
|
||||
|
||||
AutoScaleHelper {
|
||||
id: autoScale
|
||||
view3D: axisHelperView
|
||||
position: axisHelperGizmo.scenePosition
|
||||
}
|
||||
|
||||
Node {
|
||||
id: axisHelperGizmo
|
||||
scale: autoScale.getScale(Qt.vector3d(4, 4, 4))
|
||||
|
||||
AxisHelperArm {
|
||||
id: armX
|
||||
eulerRotation: Qt.vector3d(0, 0, -90)
|
||||
color: Qt.rgba(1, 0, 0, 1)
|
||||
hoverColor: Qt.lighter(Qt.rgba(1, 0, 0, 1))
|
||||
view3D: axisHelperView
|
||||
camRotPos: Qt.vector3d(0, 90, 0)
|
||||
camRotNeg: Qt.vector3d(0, -90, 0)
|
||||
}
|
||||
|
||||
AxisHelperArm {
|
||||
id: armY
|
||||
eulerRotation: Qt.vector3d(0, 0, 0)
|
||||
color: Qt.rgba(0, 0.6, 0, 1)
|
||||
hoverColor: Qt.lighter(Qt.rgba(0, 0.6, 0, 1))
|
||||
view3D: axisHelperView
|
||||
camRotPos: Qt.vector3d(-90, 0, 0)
|
||||
camRotNeg: Qt.vector3d(90, 0, 0)
|
||||
}
|
||||
|
||||
AxisHelperArm {
|
||||
id: armZ
|
||||
eulerRotation: Qt.vector3d(90, 0, 0)
|
||||
color: Qt.rgba(0, 0, 1, 1)
|
||||
hoverColor: Qt.lighter(Qt.rgba(0, 0, 1, 1))
|
||||
view3D: axisHelperView
|
||||
camRotPos: Qt.vector3d(0, 0, 0)
|
||||
camRotNeg: Qt.vector3d(0, 180, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
acceptedButtons: Qt.LeftButton
|
||||
|
||||
property var pickObj: null
|
||||
|
||||
function cancelHover()
|
||||
{
|
||||
if (pickObj) {
|
||||
pickObj.hovering = false;
|
||||
pickObj = null;
|
||||
}
|
||||
}
|
||||
|
||||
function pick(mouse)
|
||||
{
|
||||
var result = axisHelperView.pick(mouse.x, mouse.y);
|
||||
if (result.objectHit) {
|
||||
if (result.objectHit !== pickObj) {
|
||||
cancelHover();
|
||||
pickObj = result.objectHit;
|
||||
pickObj.hovering = true;
|
||||
}
|
||||
} else {
|
||||
cancelHover();
|
||||
}
|
||||
}
|
||||
|
||||
onPositionChanged: (mouse)=> {
|
||||
pick(mouse);
|
||||
}
|
||||
|
||||
onPressed: (mouse)=> {
|
||||
pick(mouse);
|
||||
if (pickObj) {
|
||||
axisHelperView.editCameraCtrl.focusObject(axisHelperView.selectedNode,
|
||||
pickObj.cameraRotation, false, false);
|
||||
} else {
|
||||
mouse.accepted = false;
|
||||
}
|
||||
}
|
||||
|
||||
onExited: cancelHover()
|
||||
onCanceled: cancelHover()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
|
||||
Node {
|
||||
id: armRoot
|
||||
property alias posModel: posModel
|
||||
property alias negModel: negModel
|
||||
property View3D view3D
|
||||
property color hoverColor
|
||||
property color color
|
||||
property vector3d camRotPos
|
||||
property vector3d camRotNeg
|
||||
|
||||
Model {
|
||||
id: posModel
|
||||
|
||||
property bool hovering: false
|
||||
property vector3d cameraRotation: armRoot.camRotPos
|
||||
|
||||
source: "../meshes/axishelper.mesh"
|
||||
materials: DefaultMaterial {
|
||||
id: posMat
|
||||
diffuseColor: posModel.hovering ? armRoot.hoverColor : armRoot.color
|
||||
lighting: DefaultMaterial.NoLighting
|
||||
}
|
||||
pickable: true
|
||||
}
|
||||
|
||||
Model {
|
||||
id: negModel
|
||||
|
||||
property bool hovering: false
|
||||
property vector3d cameraRotation: armRoot.camRotNeg
|
||||
|
||||
source: "#Sphere"
|
||||
y: -6
|
||||
scale: Qt.vector3d(0.025, 0.025, 0.025)
|
||||
materials: DefaultMaterial {
|
||||
id: negMat
|
||||
diffuseColor: negModel.hovering ? armRoot.hoverColor : armRoot.color
|
||||
lighting: DefaultMaterial.NoLighting
|
||||
}
|
||||
pickable: true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
import CameraGeometry 1.0
|
||||
|
||||
Model {
|
||||
id: cameraFrustum
|
||||
|
||||
property alias geometryName: cameraGeometry.name // Name must be unique for each geometry
|
||||
property alias viewPortRect: cameraGeometry.viewPortRect
|
||||
property Node targetNode: null
|
||||
property Node scene: null
|
||||
property bool selected: false
|
||||
|
||||
function updateGeometry()
|
||||
{
|
||||
cameraGeometry.update();
|
||||
}
|
||||
|
||||
position: targetNode ? targetNode.scenePosition : Qt.vector3d(0, 0, 0)
|
||||
rotation: targetNode ? targetNode.sceneRotation : Qt.quaternion(1, 0, 0, 0)
|
||||
|
||||
geometry: cameraGeometry
|
||||
materials: [
|
||||
DefaultMaterial {
|
||||
id: defaultMaterial
|
||||
diffuseColor: cameraFrustum.selected ? "#FF0000" : "#555555"
|
||||
lighting: DefaultMaterial.NoLighting
|
||||
cullMode: Material.NoCulling
|
||||
}
|
||||
]
|
||||
|
||||
CameraGeometry {
|
||||
id: cameraGeometry
|
||||
camera: cameraFrustum.scene && cameraFrustum.targetNode ? cameraFrustum.targetNode : null
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
|
||||
IconGizmo {
|
||||
id: cameraGizmo
|
||||
|
||||
property Model frustumModel: null
|
||||
|
||||
iconSource: "qrc:///qtquickplugin/mockfiles/images/editor_camera.png"
|
||||
|
||||
function connectFrustum(frustum)
|
||||
{
|
||||
frustumModel = frustum;
|
||||
|
||||
frustum.selected = selected;
|
||||
frustum.selected = Qt.binding(function() {return selected;});
|
||||
|
||||
frustum.scene = scene;
|
||||
frustum.scene = Qt.binding(function() {return scene;});
|
||||
|
||||
frustum.targetNode = targetNode;
|
||||
frustum.targetNode = Qt.binding(function() {return targetNode;});
|
||||
|
||||
frustum.visible = visible || (targetNode && selected && activeScene === scene);
|
||||
frustum.visible = Qt.binding(function() {return visible || (targetNode && selected && activeScene === scene);});
|
||||
}
|
||||
|
||||
onActiveSceneChanged: {
|
||||
if (frustumModel && activeScene == scene)
|
||||
frustumModel.updateGeometry();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
import MouseArea3D 1.0
|
||||
|
||||
Model {
|
||||
id: rootModel
|
||||
|
||||
property View3D view3D
|
||||
property alias color: material.diffuseColor
|
||||
property Node targetNode: null
|
||||
property bool dragging: mouseAreaYZ.dragging || mouseAreaXZ.dragging
|
||||
property bool active: false
|
||||
property MouseArea3D dragHelper: null
|
||||
property alias material: material
|
||||
property real length: 12
|
||||
property real offset: 0
|
||||
|
||||
readonly property bool hovering: mouseAreaYZ.hovering || mouseAreaXZ.hovering
|
||||
|
||||
property vector3d _scenePosPressed
|
||||
property real _posPressed
|
||||
property vector3d _targetStartPos
|
||||
|
||||
signal pressed(var mouseArea, point screenPos)
|
||||
signal dragged(var mouseArea, vector3d sceneRelativeDistance, real relativeDistance, point screenPos)
|
||||
signal released(var mouseArea, vector3d sceneRelativeDistance, real relativeDistance, point screenPos)
|
||||
|
||||
DefaultMaterial {
|
||||
id: material
|
||||
diffuseColor: "white"
|
||||
lighting: DefaultMaterial.NoLighting
|
||||
}
|
||||
|
||||
materials: [ material ]
|
||||
|
||||
function handlePressed(mouseArea, planePos, screenPos)
|
||||
{
|
||||
if (!targetNode)
|
||||
return;
|
||||
|
||||
var maskedPosition = Qt.vector3d(planePos.x, 0, 0);
|
||||
_posPressed = planePos.x;
|
||||
_scenePosPressed = mouseArea.dragHelper.mapPositionToScene(maskedPosition);
|
||||
_targetStartPos = mouseArea.pivotScenePosition(targetNode);
|
||||
pressed(mouseArea, screenPos);
|
||||
}
|
||||
|
||||
function calcRelativeDistance(mouseArea, planePos)
|
||||
{
|
||||
var maskedPosition = Qt.vector3d(planePos.x, 0, 0);
|
||||
var scenePointerPos = mouseArea.dragHelper.mapPositionToScene(maskedPosition);
|
||||
return scenePointerPos.minus(_scenePosPressed);
|
||||
}
|
||||
|
||||
function handleDragged(mouseArea, planePos, screenPos)
|
||||
{
|
||||
if (!targetNode)
|
||||
return;
|
||||
|
||||
dragged(mouseArea, calcRelativeDistance(mouseArea, planePos), planePos.x - _posPressed, screenPos);
|
||||
}
|
||||
|
||||
function handleReleased(mouseArea, planePos, screenPos)
|
||||
{
|
||||
if (!targetNode)
|
||||
return;
|
||||
|
||||
released(mouseArea, calcRelativeDistance(mouseArea, planePos), planePos.x - _posPressed, screenPos);
|
||||
}
|
||||
|
||||
MouseArea3D {
|
||||
id: mouseAreaYZ
|
||||
view3D: rootModel.view3D
|
||||
x: rootModel.offset
|
||||
y: -1.5
|
||||
width: rootModel.length
|
||||
height: 3
|
||||
eulerRotation: Qt.vector3d(0, 0, 90)
|
||||
grabsMouse: targetNode
|
||||
active: rootModel.active
|
||||
dragHelper: rootModel.dragHelper
|
||||
priority: 5
|
||||
|
||||
onPressed: (planePos, screenPos)=> {
|
||||
rootModel.handlePressed(mouseAreaYZ, planePos, screenPos);
|
||||
}
|
||||
onDragged: (planePos, screenPos)=> {
|
||||
rootModel.handleDragged(mouseAreaYZ, planePos, screenPos);
|
||||
}
|
||||
onReleased: (planePos, screenPos)=> {
|
||||
rootModel.handleReleased(mouseAreaYZ, planePos, screenPos);
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea3D {
|
||||
id: mouseAreaXZ
|
||||
view3D: rootModel.view3D
|
||||
x: rootModel.offset
|
||||
y: -1.5
|
||||
width: rootModel.length
|
||||
height: 3
|
||||
eulerRotation: Qt.vector3d(0, 90, 90)
|
||||
grabsMouse: targetNode
|
||||
active: rootModel.active
|
||||
dragHelper: rootModel.dragHelper
|
||||
priority: 5
|
||||
|
||||
onPressed: (planePos, screenPos)=> {
|
||||
rootModel.handlePressed(mouseAreaXZ, planePos, screenPos);
|
||||
}
|
||||
onDragged: (planePos, screenPos)=> {
|
||||
rootModel.handleDragged(mouseAreaXZ, planePos, screenPos);
|
||||
}
|
||||
onReleased: (planePos, screenPos)=> {
|
||||
rootModel.handleReleased(mouseAreaXZ, planePos, screenPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
|
||||
Item {
|
||||
id: cameraCtrl
|
||||
|
||||
property Camera camera: null
|
||||
property View3D view3d: null
|
||||
property string sceneId
|
||||
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
|
||||
readonly property vector3d _defaultCameraPosition: Qt.vector3d(0, 600, 600)
|
||||
readonly property vector3d _defaultCameraRotation: Qt.vector3d(-45, 0, 0)
|
||||
readonly property real _defaultCameraLookAtDistance: _defaultCameraPosition.length()
|
||||
property bool ignoreToolState: false
|
||||
|
||||
function restoreCameraState(cameraState)
|
||||
{
|
||||
if (!camera || ignoreToolState)
|
||||
return;
|
||||
|
||||
_lookAtPoint = cameraState[0];
|
||||
_zoomFactor = cameraState[1];
|
||||
camera.position = cameraState[2];
|
||||
camera.rotation = cameraState[3];
|
||||
_generalHelper.zoomCamera(camera, 0, _defaultCameraLookAtDistance, _lookAtPoint,
|
||||
_zoomFactor, false);
|
||||
}
|
||||
|
||||
function restoreDefaultState()
|
||||
{
|
||||
if (!camera)
|
||||
return;
|
||||
|
||||
_lookAtPoint = Qt.vector3d(0, 0, 0);
|
||||
_zoomFactor = 1;
|
||||
camera.position = _defaultCameraPosition;
|
||||
camera.eulerRotation = _defaultCameraRotation;
|
||||
_generalHelper.zoomCamera(camera, 0, _defaultCameraLookAtDistance, _lookAtPoint,
|
||||
_zoomFactor, false);
|
||||
}
|
||||
|
||||
function storeCameraState(delay)
|
||||
{
|
||||
if (!camera || ignoreToolState)
|
||||
return;
|
||||
|
||||
var cameraState = [];
|
||||
cameraState[0] = _lookAtPoint;
|
||||
cameraState[1] = _zoomFactor;
|
||||
cameraState[2] = camera.position;
|
||||
cameraState[3] = camera.rotation;
|
||||
_generalHelper.storeToolState(sceneId, "editCamState", cameraState, delay);
|
||||
}
|
||||
|
||||
|
||||
function focusObject(targetObject, rotation, updateZoom, closeUp)
|
||||
{
|
||||
if (!camera)
|
||||
return;
|
||||
|
||||
camera.eulerRotation = rotation;
|
||||
var newLookAtAndZoom = _generalHelper.focusObjectToCamera(
|
||||
camera, _defaultCameraLookAtDistance, targetObject, view3d, _zoomFactor,
|
||||
updateZoom, closeUp);
|
||||
_lookAtPoint = newLookAtAndZoom.toVector3d();
|
||||
_zoomFactor = newLookAtAndZoom.w;
|
||||
storeCameraState(0);
|
||||
}
|
||||
|
||||
function zoomRelative(distance)
|
||||
{
|
||||
if (!camera)
|
||||
return;
|
||||
|
||||
_zoomFactor = _generalHelper.zoomCamera(camera, distance, _defaultCameraLookAtDistance,
|
||||
_lookAtPoint, _zoomFactor, true);
|
||||
}
|
||||
|
||||
onCameraChanged: {
|
||||
if (camera && _prevCamera) {
|
||||
// Reset zoom on previous camera to ensure it's properties are good to copy to new cam
|
||||
_generalHelper.zoomCamera(_prevCamera, 0, _defaultCameraLookAtDistance, _lookAtPoint,
|
||||
1, false);
|
||||
|
||||
camera.position = _prevCamera.position;
|
||||
camera.rotation = _prevCamera.rotation;
|
||||
|
||||
// Apply correct zoom to new camera
|
||||
_generalHelper.zoomCamera(camera, 0, _defaultCameraLookAtDistance, _lookAtPoint,
|
||||
_zoomFactor, false);
|
||||
}
|
||||
_prevCamera = camera;
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouseHandler
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
|
||||
hoverEnabled: false
|
||||
anchors.fill: parent
|
||||
onPositionChanged: (mouse)=> {
|
||||
if (cameraCtrl.camera && mouse.modifiers === Qt.AltModifier && cameraCtrl._dragging) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
onPressed: (mouse)=> {
|
||||
if (cameraCtrl.camera && mouse.modifiers === Qt.AltModifier) {
|
||||
cameraCtrl._dragging = true;
|
||||
cameraCtrl._startRotation = cameraCtrl.camera.eulerRotation;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
function handleRelease() {
|
||||
cameraCtrl._dragging = false;
|
||||
cameraCtrl.storeCameraState(0);
|
||||
}
|
||||
|
||||
onReleased: handleRelease()
|
||||
onCanceled: handleRelease()
|
||||
|
||||
onWheel: (wheel)=> {
|
||||
if (cameraCtrl.camera) {
|
||||
// Empirically determined divisor for nice zoom
|
||||
cameraCtrl.zoomRelative(wheel.angleDelta.y / -40);
|
||||
cameraCtrl.storeCameraState(500);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,884 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
import MouseArea3D 1.0
|
||||
|
||||
Item {
|
||||
id: viewRoot
|
||||
width: 1024
|
||||
height: 768
|
||||
visible: true
|
||||
|
||||
property Node activeScene: null
|
||||
property View3D editView: null
|
||||
property string sceneId
|
||||
|
||||
property bool showEditLight: false
|
||||
property bool showGrid: true
|
||||
property bool usePerspective: true
|
||||
property bool globalOrientation: false
|
||||
property alias contentItem: contentItem
|
||||
|
||||
enum SelectionMode { Item, Group }
|
||||
enum TransformMode { Move, Rotate, Scale }
|
||||
|
||||
property int selectionMode: EditView3D.SelectionMode.Item
|
||||
property int transformMode: EditView3D.TransformMode.Move
|
||||
|
||||
property Node selectedNode: null // This is multiSelectionNode in multi-selection case
|
||||
property var selectedNodes: [] // All selected nodes
|
||||
|
||||
property var lightIconGizmos: []
|
||||
property var cameraGizmos: []
|
||||
property var selectionBoxes: []
|
||||
property rect viewPortRect: Qt.rect(0, 0, 1000, 1000)
|
||||
|
||||
property bool shuttingDown: false
|
||||
|
||||
property real fps: 0
|
||||
|
||||
signal selectionChanged(var selectedNodes)
|
||||
signal commitObjectProperty(var objects, var propNames)
|
||||
signal changeObjectProperty(var objects, var propNames)
|
||||
signal notifyActiveSceneChange()
|
||||
|
||||
onUsePerspectiveChanged: _generalHelper.storeToolState(sceneId, "usePerspective", usePerspective)
|
||||
onShowEditLightChanged: _generalHelper.storeToolState(sceneId, "showEditLight", showEditLight)
|
||||
onGlobalOrientationChanged: _generalHelper.storeToolState(sceneId, "globalOrientation", globalOrientation)
|
||||
onShowGridChanged: _generalHelper.storeToolState(sceneId, "showGrid", showGrid);
|
||||
onSelectionModeChanged: _generalHelper.storeToolState(sceneId, "selectionMode", selectionMode);
|
||||
onTransformModeChanged: _generalHelper.storeToolState(sceneId, "transformMode", transformMode);
|
||||
|
||||
onActiveSceneChanged: updateActiveScene()
|
||||
|
||||
function aboutToShutDown()
|
||||
{
|
||||
shuttingDown = true;
|
||||
}
|
||||
|
||||
function createEditView()
|
||||
{
|
||||
var component = Qt.createComponent("SceneView3D.qml");
|
||||
if (component.status === Component.Ready) {
|
||||
editView = component.createObject(viewRect,
|
||||
{"usePerspective": usePerspective,
|
||||
"showSceneLight": showEditLight,
|
||||
"showGrid": showGrid,
|
||||
"importScene": activeScene,
|
||||
"cameraZoomFactor": cameraControl._zoomFactor,
|
||||
"z": 1});
|
||||
editView.usePerspective = Qt.binding(function() {return usePerspective;});
|
||||
editView.showSceneLight = Qt.binding(function() {return showEditLight;});
|
||||
editView.showGrid = Qt.binding(function() {return showGrid;});
|
||||
editView.cameraZoomFactor = Qt.binding(function() {return cameraControl._zoomFactor;});
|
||||
|
||||
selectionBoxes.length = 0;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function updateActiveScene()
|
||||
{
|
||||
if (editView) {
|
||||
// Destroy is async, so make sure we don't get any more updates for the old editView
|
||||
_generalHelper.enableItemUpdate(editView, false);
|
||||
editView.visible = false;
|
||||
editView.destroy();
|
||||
}
|
||||
|
||||
// importScene cannot be updated after initial set, so we need to reconstruct entire View3D
|
||||
if (createEditView()) {
|
||||
if (activeScene) {
|
||||
var toolStates = _generalHelper.getToolStates(sceneId);
|
||||
if (Object.keys(toolStates).length > 0) {
|
||||
updateToolStates(toolStates, true);
|
||||
} else {
|
||||
// Don't inherit the edit light state from the previous scene, but rather
|
||||
// turn the edit light on for scenes that do not have any scene
|
||||
// lights, and turn it off for scenes that have.
|
||||
var hasSceneLight = false;
|
||||
for (var i = 0; i < lightIconGizmos.length; ++i) {
|
||||
if (lightIconGizmos[i].scene === activeScene) {
|
||||
hasSceneLight = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
showEditLight = !hasSceneLight;
|
||||
storeCurrentToolStates();
|
||||
}
|
||||
} else {
|
||||
// When active scene is deleted, this function gets called by object deletion
|
||||
// handlers without going through setActiveScene, so make sure sceneId is cleared.
|
||||
// This is skipped during application shutdown, as calling QQuickText::setText()
|
||||
// during application shutdown can crash the application.
|
||||
if (!shuttingDown) {
|
||||
sceneId = "";
|
||||
storeCurrentToolStates();
|
||||
}
|
||||
}
|
||||
|
||||
notifyActiveSceneChange();
|
||||
}
|
||||
}
|
||||
|
||||
function setActiveScene(newScene, newSceneId)
|
||||
{
|
||||
var needExplicitUpdate = !activeScene && !newScene;
|
||||
|
||||
sceneId = newSceneId;
|
||||
activeScene = newScene;
|
||||
|
||||
if (needExplicitUpdate)
|
||||
updateActiveScene();
|
||||
}
|
||||
|
||||
// Disables edit view update if scene doesn't match current activeScene.
|
||||
// If it matches, updates are enabled.
|
||||
function enableEditViewUpdate(scene)
|
||||
{
|
||||
if (editView)
|
||||
_generalHelper.enableItemUpdate(editView, (scene && scene === activeScene));
|
||||
}
|
||||
|
||||
function handleActiveSceneIdChange(newId)
|
||||
{
|
||||
if (sceneId !== newId) {
|
||||
sceneId = newId;
|
||||
storeCurrentToolStates();
|
||||
}
|
||||
}
|
||||
|
||||
function fitToView()
|
||||
{
|
||||
if (editView) {
|
||||
var targetNode = selectionBoxes.length > 0
|
||||
? selectionBoxes[0].model : null;
|
||||
cameraControl.focusObject(targetNode, editView.camera.eulerRotation, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
// If resetToDefault is true, tool states not specifically set to anything will be reset to
|
||||
// their default state.
|
||||
function updateToolStates(toolStates, resetToDefault)
|
||||
{
|
||||
if ("showEditLight" in toolStates)
|
||||
showEditLight = toolStates.showEditLight;
|
||||
else if (resetToDefault)
|
||||
showEditLight = false;
|
||||
|
||||
if ("showGrid" in toolStates)
|
||||
showGrid = toolStates.showGrid;
|
||||
else if (resetToDefault)
|
||||
showGrid = true;
|
||||
|
||||
if ("usePerspective" in toolStates)
|
||||
usePerspective = toolStates.usePerspective;
|
||||
else if (resetToDefault)
|
||||
usePerspective = true;
|
||||
|
||||
if ("globalOrientation" in toolStates)
|
||||
globalOrientation = toolStates.globalOrientation;
|
||||
else if (resetToDefault)
|
||||
globalOrientation = false;
|
||||
|
||||
if ("selectionMode" in toolStates)
|
||||
selectionMode = toolStates.selectionMode;
|
||||
else if (resetToDefault)
|
||||
selectionMode = EditView3D.SelectionMode.Item;
|
||||
|
||||
if ("transformMode" in toolStates)
|
||||
transformMode = toolStates.transformMode;
|
||||
else if (resetToDefault)
|
||||
transformMode = EditView3D.TransformMode.Move;
|
||||
|
||||
if ("editCamState" in toolStates)
|
||||
cameraControl.restoreCameraState(toolStates.editCamState);
|
||||
else if (resetToDefault)
|
||||
cameraControl.restoreDefaultState();
|
||||
}
|
||||
|
||||
function storeCurrentToolStates()
|
||||
{
|
||||
_generalHelper.storeToolState(sceneId, "showEditLight", showEditLight)
|
||||
_generalHelper.storeToolState(sceneId, "showGrid", showGrid)
|
||||
_generalHelper.storeToolState(sceneId, "usePerspective", usePerspective)
|
||||
_generalHelper.storeToolState(sceneId, "globalOrientation", globalOrientation)
|
||||
_generalHelper.storeToolState(sceneId, "selectionMode", selectionMode);
|
||||
_generalHelper.storeToolState(sceneId, "transformMode", transformMode);
|
||||
|
||||
cameraControl.storeCameraState(0);
|
||||
}
|
||||
|
||||
function ensureSelectionBoxes(count)
|
||||
{
|
||||
var needMore = count - selectionBoxes.length
|
||||
if (needMore > 0) {
|
||||
var component = Qt.createComponent("SelectionBox.qml");
|
||||
if (component.status === Component.Ready) {
|
||||
for (var i = 0; i < needMore; ++i) {
|
||||
var geometryName = _generalHelper.generateUniqueName("SelectionBoxGeometry");
|
||||
var boxParent = null;
|
||||
if (editView)
|
||||
boxParent = editView.sceneHelpers;
|
||||
var box = component.createObject(boxParent, {"view3D": editView,
|
||||
"geometryName": geometryName});
|
||||
selectionBoxes[selectionBoxes.length] = box;
|
||||
box.view3D = Qt.binding(function() {return editView;});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function selectObjects(objects)
|
||||
{
|
||||
// Create selection boxes as necessary. One more box than is actually needed is created, so
|
||||
// that we always have a previously created box to use for new selection.
|
||||
// This fixes an occasional visual glitch when creating a new box.
|
||||
ensureSelectionBoxes(objects.length + 1)
|
||||
|
||||
var i;
|
||||
for (i = 0; i < objects.length; ++i)
|
||||
selectionBoxes[i].targetNode = objects[i];
|
||||
for (i = objects.length; i < selectionBoxes.length; ++i)
|
||||
selectionBoxes[i].targetNode = null;
|
||||
|
||||
selectedNodes = objects;
|
||||
if (objects.length === 0) {
|
||||
selectedNode = null;
|
||||
} else if (objects.length > 1) {
|
||||
selectedNode = multiSelectionNode;
|
||||
_generalHelper.setMultiSelectionTargets(multiSelectionNode, objects);
|
||||
} else {
|
||||
selectedNode = objects[0];
|
||||
}
|
||||
}
|
||||
|
||||
function handleObjectClicked(object, multi)
|
||||
{
|
||||
var clickedObject;
|
||||
|
||||
// Click on locked object is treated same as click on empty space
|
||||
if (!_generalHelper.isLocked(object))
|
||||
clickedObject = object;
|
||||
|
||||
if (selectionMode === EditView3D.SelectionMode.Group) {
|
||||
while (clickedObject && clickedObject !== activeScene
|
||||
&& (activeScene instanceof Model || clickedObject.parent !== activeScene)) {
|
||||
clickedObject = clickedObject.parent;
|
||||
}
|
||||
}
|
||||
// Object selection logic:
|
||||
// Regular click: Clear any multiselection, single-selects the clicked object
|
||||
// Ctrl-click: No objects selected: Act as single select
|
||||
// One or more objects selected: Multiselect
|
||||
// Null object always clears entire selection
|
||||
var newSelection = [];
|
||||
if (clickedObject) {
|
||||
if (multi && selectedNodes.length > 0) {
|
||||
var deselect = false;
|
||||
for (var i = 0; i < selectedNodes.length; ++i) {
|
||||
// Multiselecting already selected object clears that object from selection
|
||||
if (selectedNodes[i] !== clickedObject)
|
||||
newSelection[newSelection.length] = selectedNodes[i];
|
||||
else
|
||||
deselect = true;
|
||||
}
|
||||
if (!deselect)
|
||||
newSelection[newSelection.length] = clickedObject;
|
||||
} else {
|
||||
newSelection[0] = clickedObject;
|
||||
}
|
||||
}
|
||||
selectObjects(newSelection);
|
||||
selectionChanged(newSelection);
|
||||
}
|
||||
|
||||
function addLightGizmo(scene, obj)
|
||||
{
|
||||
// Insert into first available gizmo if we don't already have gizmo for this object
|
||||
var slotFound = -1;
|
||||
for (var i = 0; i < lightIconGizmos.length; ++i) {
|
||||
if (!lightIconGizmos[i].targetNode) {
|
||||
slotFound = i;
|
||||
} else if (lightIconGizmos[i].targetNode === obj) {
|
||||
lightIconGizmos[i].scene = scene;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (slotFound !== -1) {
|
||||
lightIconGizmos[slotFound].scene = scene;
|
||||
lightIconGizmos[slotFound].targetNode = obj;
|
||||
lightIconGizmos[slotFound].locked = _generalHelper.isLocked(obj);
|
||||
lightIconGizmos[slotFound].hidden = _generalHelper.isHidden(obj);
|
||||
_generalHelper.registerGizmoTarget(obj);
|
||||
return;
|
||||
}
|
||||
|
||||
// No free gizmos available, create a new one
|
||||
var gizmoComponent = Qt.createComponent("LightIconGizmo.qml");
|
||||
if (gizmoComponent.status === Component.Ready) {
|
||||
_generalHelper.registerGizmoTarget(obj);
|
||||
var gizmo = gizmoComponent.createObject(overlayView,
|
||||
{"view3D": overlayView, "targetNode": obj,
|
||||
"selectedNodes": selectedNodes, "scene": scene,
|
||||
"activeScene": activeScene,
|
||||
"locked": _generalHelper.isLocked(obj),
|
||||
"hidden": _generalHelper.isHidden(obj)});
|
||||
lightIconGizmos[lightIconGizmos.length] = gizmo;
|
||||
gizmo.clicked.connect(handleObjectClicked);
|
||||
gizmo.selectedNodes = Qt.binding(function() {return selectedNodes;});
|
||||
gizmo.activeScene = Qt.binding(function() {return activeScene;});
|
||||
}
|
||||
}
|
||||
|
||||
function addCameraGizmo(scene, obj)
|
||||
{
|
||||
// Insert into first available gizmo if we don't already have gizmo for this object
|
||||
var slotFound = -1;
|
||||
for (var i = 0; i < cameraGizmos.length; ++i) {
|
||||
if (!cameraGizmos[i].targetNode) {
|
||||
slotFound = i;
|
||||
} else if (cameraGizmos[i].targetNode === obj) {
|
||||
cameraGizmos[i].scene = scene;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (slotFound !== -1) {
|
||||
cameraGizmos[slotFound].scene = scene;
|
||||
cameraGizmos[slotFound].targetNode = obj;
|
||||
cameraGizmos[slotFound].locked = _generalHelper.isLocked(obj);
|
||||
cameraGizmos[slotFound].hidden = _generalHelper.isHidden(obj);
|
||||
_generalHelper.registerGizmoTarget(obj);
|
||||
return;
|
||||
}
|
||||
|
||||
// No free gizmos available, create a new one
|
||||
var gizmoComponent = Qt.createComponent("CameraGizmo.qml");
|
||||
var frustumComponent = Qt.createComponent("CameraFrustum.qml");
|
||||
if (gizmoComponent.status === Component.Ready && frustumComponent.status === Component.Ready) {
|
||||
_generalHelper.registerGizmoTarget(obj);
|
||||
var geometryName = _generalHelper.generateUniqueName("CameraGeometry");
|
||||
var frustum = frustumComponent.createObject(
|
||||
overlayScene,
|
||||
{"geometryName": geometryName, "viewPortRect": viewPortRect});
|
||||
var gizmo = gizmoComponent.createObject(
|
||||
overlayView,
|
||||
{"view3D": overlayView, "targetNode": obj,
|
||||
"selectedNodes": selectedNodes, "scene": scene, "activeScene": activeScene,
|
||||
"locked": _generalHelper.isLocked(obj), "hidden": _generalHelper.isHidden(obj)});
|
||||
|
||||
cameraGizmos[cameraGizmos.length] = gizmo;
|
||||
gizmo.clicked.connect(handleObjectClicked);
|
||||
gizmo.selectedNodes = Qt.binding(function() {return selectedNodes;});
|
||||
gizmo.activeScene = Qt.binding(function() {return activeScene;});
|
||||
frustum.viewPortRect = Qt.binding(function() {return viewPortRect;});
|
||||
gizmo.connectFrustum(frustum);
|
||||
}
|
||||
}
|
||||
|
||||
function releaseLightGizmo(obj)
|
||||
{
|
||||
for (var i = 0; i < lightIconGizmos.length; ++i) {
|
||||
if (lightIconGizmos[i].targetNode === obj) {
|
||||
lightIconGizmos[i].scene = null;
|
||||
lightIconGizmos[i].targetNode = null;
|
||||
_generalHelper.unregisterGizmoTarget(obj);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function releaseCameraGizmo(obj)
|
||||
{
|
||||
for (var i = 0; i < cameraGizmos.length; ++i) {
|
||||
if (cameraGizmos[i].targetNode === obj) {
|
||||
cameraGizmos[i].scene = null;
|
||||
cameraGizmos[i].targetNode = null;
|
||||
_generalHelper.unregisterGizmoTarget(obj);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateLightGizmoScene(scene, obj)
|
||||
{
|
||||
for (var i = 0; i < lightIconGizmos.length; ++i) {
|
||||
if (lightIconGizmos[i].targetNode === obj) {
|
||||
lightIconGizmos[i].scene = scene;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateCameraGizmoScene(scene, obj)
|
||||
{
|
||||
for (var i = 0; i < cameraGizmos.length; ++i) {
|
||||
if (cameraGizmos[i].targetNode === obj) {
|
||||
cameraGizmos[i].scene = scene;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
createEditView();
|
||||
selectObjects([]);
|
||||
// Work-around the fact that the projection matrix for the camera is not calculated until
|
||||
// the first frame is rendered, so any initial calls to mapFrom3DScene() will fail.
|
||||
_generalHelper.requestOverlayUpdate();
|
||||
}
|
||||
|
||||
onWidthChanged: _generalHelper.requestOverlayUpdate()
|
||||
onHeightChanged: _generalHelper.requestOverlayUpdate()
|
||||
|
||||
Connections {
|
||||
target: _generalHelper
|
||||
function onLockedStateChanged(node)
|
||||
{
|
||||
for (var i = 0; i < cameraGizmos.length; ++i) {
|
||||
if (cameraGizmos[i].targetNode === node) {
|
||||
cameraGizmos[i].locked = _generalHelper.isLocked(node);
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < lightIconGizmos.length; ++i) {
|
||||
if (lightIconGizmos[i].targetNode === node) {
|
||||
lightIconGizmos[i].locked = _generalHelper.isLocked(node);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
function onHiddenStateChanged(node)
|
||||
{
|
||||
for (var i = 0; i < cameraGizmos.length; ++i) {
|
||||
if (cameraGizmos[i].targetNode === node) {
|
||||
cameraGizmos[i].hidden = _generalHelper.isHidden(node);
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < lightIconGizmos.length; ++i) {
|
||||
if (lightIconGizmos[i].targetNode === node) {
|
||||
lightIconGizmos[i].hidden = _generalHelper.isHidden(node);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Node {
|
||||
id: overlayScene
|
||||
|
||||
PerspectiveCamera {
|
||||
id: overlayPerspectiveCamera
|
||||
clipFar: viewRoot.editView ? viewRoot.editView.perspectiveCamera.clipFar : 1000
|
||||
clipNear: viewRoot.editView ? viewRoot.editView.perspectiveCamera.clipNear : 1
|
||||
position: viewRoot.editView ? viewRoot.editView.perspectiveCamera.position : Qt.vector3d(0, 0, 0)
|
||||
rotation: viewRoot.editView ? viewRoot.editView.perspectiveCamera.rotation : Qt.quaternion(1, 0, 0, 0)
|
||||
}
|
||||
|
||||
OrthographicCamera {
|
||||
id: overlayOrthoCamera
|
||||
clipFar: viewRoot.editView ? viewRoot.editView.orthoCamera.clipFar : 1000
|
||||
clipNear: viewRoot.editView ? viewRoot.editView.orthoCamera.clipNear : 1
|
||||
position: viewRoot.editView ? viewRoot.editView.orthoCamera.position : Qt.vector3d(0, 0, 0)
|
||||
rotation: viewRoot.editView ? viewRoot.editView.orthoCamera.rotation : Qt.quaternion(1, 0, 0, 0)
|
||||
scale: viewRoot.editView ? viewRoot.editView.orthoCamera.scale : Qt.vector3d(0, 0, 0)
|
||||
}
|
||||
|
||||
MouseArea3D {
|
||||
id: gizmoDragHelper
|
||||
view3D: overlayView
|
||||
}
|
||||
|
||||
Node {
|
||||
id: multiSelectionNode
|
||||
objectName: "multiSelectionNode"
|
||||
}
|
||||
|
||||
MoveGizmo {
|
||||
id: moveGizmo
|
||||
scale: autoScale.getScale(Qt.vector3d(5, 5, 5))
|
||||
highlightOnHover: true
|
||||
targetNode: viewRoot.selectedNode
|
||||
globalOrientation: viewRoot.globalOrientation
|
||||
visible: viewRoot.selectedNode && transformMode === EditView3D.TransformMode.Move
|
||||
view3D: overlayView
|
||||
dragHelper: gizmoDragHelper
|
||||
property var propertyNames: ["position"]
|
||||
|
||||
onPositionCommit: {
|
||||
if (targetNode == multiSelectionNode)
|
||||
viewRoot.commitObjectProperty(_generalHelper.multiSelectionTargets(), propertyNames);
|
||||
else
|
||||
viewRoot.commitObjectProperty([viewRoot.selectedNode], propertyNames);
|
||||
}
|
||||
onPositionMove: {
|
||||
if (targetNode == multiSelectionNode)
|
||||
viewRoot.changeObjectProperty(_generalHelper.multiSelectionTargets(), propertyNames);
|
||||
else
|
||||
viewRoot.changeObjectProperty([viewRoot.selectedNode], propertyNames);
|
||||
}
|
||||
}
|
||||
|
||||
ScaleGizmo {
|
||||
id: scaleGizmo
|
||||
scale: autoScale.getScale(Qt.vector3d(5, 5, 5))
|
||||
highlightOnHover: true
|
||||
targetNode: viewRoot.selectedNode
|
||||
visible: viewRoot.selectedNode && transformMode === EditView3D.TransformMode.Scale
|
||||
view3D: overlayView
|
||||
dragHelper: gizmoDragHelper
|
||||
property var propertyNames: ["scale"]
|
||||
property var propertyNamesMulti: ["position", "scale"]
|
||||
|
||||
onScaleCommit: {
|
||||
if (targetNode == multiSelectionNode)
|
||||
viewRoot.commitObjectProperty(_generalHelper.multiSelectionTargets(), propertyNamesMulti);
|
||||
else
|
||||
viewRoot.commitObjectProperty([viewRoot.selectedNode], propertyNames);
|
||||
}
|
||||
onScaleChange: {
|
||||
if (targetNode == multiSelectionNode)
|
||||
viewRoot.changeObjectProperty(_generalHelper.multiSelectionTargets(), propertyNamesMulti);
|
||||
else
|
||||
viewRoot.changeObjectProperty([viewRoot.selectedNode], propertyNames);
|
||||
}
|
||||
}
|
||||
|
||||
RotateGizmo {
|
||||
id: rotateGizmo
|
||||
scale: autoScale.getScale(Qt.vector3d(7, 7, 7))
|
||||
highlightOnHover: true
|
||||
targetNode: viewRoot.selectedNode
|
||||
globalOrientation: viewRoot.globalOrientation
|
||||
visible: viewRoot.selectedNode && transformMode === EditView3D.TransformMode.Rotate
|
||||
view3D: overlayView
|
||||
dragHelper: gizmoDragHelper
|
||||
property var propertyNames: ["eulerRotation"]
|
||||
property var propertyNamesMulti: ["position", "eulerRotation"]
|
||||
|
||||
onRotateCommit: {
|
||||
if (targetNode == multiSelectionNode)
|
||||
viewRoot.commitObjectProperty(_generalHelper.multiSelectionTargets(), propertyNamesMulti);
|
||||
else
|
||||
viewRoot.commitObjectProperty([viewRoot.selectedNode], propertyNames);
|
||||
}
|
||||
onRotateChange: {
|
||||
if (targetNode == multiSelectionNode)
|
||||
viewRoot.changeObjectProperty(_generalHelper.multiSelectionTargets(), propertyNamesMulti);
|
||||
else
|
||||
viewRoot.changeObjectProperty([viewRoot.selectedNode], propertyNames);
|
||||
}
|
||||
}
|
||||
|
||||
LightGizmo {
|
||||
id: lightGizmo
|
||||
targetNode: viewRoot.selectedNode != multiSelectionNode ? viewRoot.selectedNode : null
|
||||
view3D: overlayView
|
||||
dragHelper: gizmoDragHelper
|
||||
|
||||
onPropertyValueCommit: (propName)=> {
|
||||
viewRoot.commitObjectProperty([targetNode], [propName]);
|
||||
}
|
||||
onPropertyValueChange: (propName)=> {
|
||||
viewRoot.changeObjectProperty([targetNode], [propName]);
|
||||
}
|
||||
}
|
||||
|
||||
AutoScaleHelper {
|
||||
id: autoScale
|
||||
view3D: overlayView
|
||||
position: moveGizmo.scenePosition
|
||||
}
|
||||
|
||||
AutoScaleHelper {
|
||||
id: pivotAutoScale
|
||||
view3D: overlayView
|
||||
position: pivotLine.startPos
|
||||
}
|
||||
|
||||
Line3D {
|
||||
id: pivotLine
|
||||
visible: viewRoot.selectedNode && viewRoot.selectedNode != multiSelectionNode
|
||||
name: "3D Edit View Pivot Line"
|
||||
color: "#ddd600"
|
||||
|
||||
startPos: viewRoot.selectedNode ? viewRoot.selectedNode.scenePosition
|
||||
: Qt.vector3d(0, 0, 0)
|
||||
Connections {
|
||||
target: viewRoot
|
||||
function onSelectedNodeChanged()
|
||||
{
|
||||
pivotLine.endPos = gizmoDragHelper.pivotScenePosition(viewRoot.selectedNode);
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: viewRoot.selectedNode
|
||||
function onSceneTransformChanged()
|
||||
{
|
||||
pivotLine.endPos = gizmoDragHelper.pivotScenePosition(viewRoot.selectedNode);
|
||||
}
|
||||
}
|
||||
|
||||
Model {
|
||||
id: pivotCap
|
||||
source: "#Sphere"
|
||||
scale: pivotAutoScale.getScale(Qt.vector3d(0.03, 0.03, 0.03))
|
||||
position: pivotLine.startPos
|
||||
materials: [
|
||||
DefaultMaterial {
|
||||
id: lineMat
|
||||
lighting: DefaultMaterial.NoLighting
|
||||
cullMode: Material.NoCulling
|
||||
diffuseColor: pivotLine.color
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: contentItem
|
||||
anchors.fill: parent
|
||||
|
||||
Rectangle {
|
||||
id: viewRect
|
||||
anchors.fill: parent
|
||||
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 1.0; color: "#222222" }
|
||||
GradientStop { position: 0.0; color: "#999999" }
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton
|
||||
hoverEnabled: false
|
||||
|
||||
property MouseArea3D freeDraggerArea
|
||||
property point pressPoint
|
||||
property bool initialMoveBlock: false
|
||||
|
||||
onPressed: (mouse)=> {
|
||||
if (viewRoot.editView) {
|
||||
var pickResult = viewRoot.editView.pick(mouse.x, mouse.y);
|
||||
handleObjectClicked(_generalHelper.resolvePick(pickResult.objectHit),
|
||||
mouse.modifiers & Qt.ControlModifier);
|
||||
|
||||
if (pickResult.objectHit) {
|
||||
if (transformMode === EditView3D.TransformMode.Move)
|
||||
freeDraggerArea = moveGizmo.freeDraggerArea;
|
||||
else if (transformMode === EditView3D.TransformMode.Rotate)
|
||||
freeDraggerArea = rotateGizmo.freeDraggerArea;
|
||||
else if (transformMode === EditView3D.TransformMode.Scale)
|
||||
freeDraggerArea = scaleGizmo.freeDraggerArea;
|
||||
pressPoint.x = mouse.x;
|
||||
pressPoint.y = mouse.y;
|
||||
initialMoveBlock = true;
|
||||
} else {
|
||||
mouse.accepted = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
onPositionChanged: (mouse)=> {
|
||||
if (freeDraggerArea) {
|
||||
if (initialMoveBlock && Math.abs(pressPoint.x - mouse.x) + Math.abs(pressPoint.y - mouse.y) > 10) {
|
||||
// Don't force press event at actual press, as that puts the gizmo
|
||||
// in free-dragging state, which is bad UX if drag is not actually done
|
||||
freeDraggerArea.forcePressEvent(pressPoint.x, pressPoint.y);
|
||||
freeDraggerArea.forceMoveEvent(mouse.x, mouse.y);
|
||||
initialMoveBlock = false;
|
||||
} else {
|
||||
freeDraggerArea.forceMoveEvent(mouse.x, mouse.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleRelease(mouse)
|
||||
{
|
||||
if (freeDraggerArea) {
|
||||
if (initialMoveBlock)
|
||||
freeDraggerArea.forceReleaseEvent(pressPoint.x, pressPoint.y);
|
||||
else
|
||||
freeDraggerArea.forceReleaseEvent(mouse.x, mouse.y);
|
||||
freeDraggerArea = null;
|
||||
}
|
||||
}
|
||||
|
||||
onReleased: (mouse)=> {
|
||||
handleRelease(mouse);
|
||||
}
|
||||
onCanceled: (mouse)=> {
|
||||
handleRelease(mouse);
|
||||
}
|
||||
}
|
||||
|
||||
DropArea {
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
View3D {
|
||||
id: overlayView
|
||||
anchors.fill: parent
|
||||
camera: viewRoot.usePerspective ? overlayPerspectiveCamera : overlayOrthoCamera
|
||||
importScene: overlayScene
|
||||
z: 2
|
||||
}
|
||||
|
||||
Overlay2D {
|
||||
id: gizmoLabel
|
||||
targetNode: moveGizmo.visible ? moveGizmo : scaleGizmo
|
||||
targetView: overlayView
|
||||
visible: targetNode.dragging
|
||||
z: 3
|
||||
|
||||
Rectangle {
|
||||
color: "white"
|
||||
x: -width / 2
|
||||
y: -height - 8
|
||||
width: gizmoLabelText.width + 4
|
||||
height: gizmoLabelText.height + 4
|
||||
border.width: 1
|
||||
Text {
|
||||
id: gizmoLabelText
|
||||
text: {
|
||||
// This is skipped during application shutdown, as calling QQuickText::setText()
|
||||
// during application shutdown can crash the application.
|
||||
if (shuttingDown)
|
||||
return text;
|
||||
var l = Qt.locale();
|
||||
var targetProperty;
|
||||
if (viewRoot.selectedNode) {
|
||||
if (gizmoLabel.targetNode === moveGizmo)
|
||||
targetProperty = viewRoot.selectedNode.position;
|
||||
else
|
||||
targetProperty = viewRoot.selectedNode.scale;
|
||||
return qsTr("x:") + Number(targetProperty.x).toLocaleString(l, 'f', 1)
|
||||
+ qsTr(" y:") + Number(targetProperty.y).toLocaleString(l, 'f', 1)
|
||||
+ qsTr(" z:") + Number(targetProperty.z).toLocaleString(l, 'f', 1);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rotateGizmoLabel
|
||||
color: "white"
|
||||
x: rotateGizmo.currentMousePos.x - (10 + width)
|
||||
y: rotateGizmo.currentMousePos.y - (10 + height)
|
||||
width: rotateGizmoLabelText.width + 4
|
||||
height: rotateGizmoLabelText.height + 4
|
||||
border.width: 1
|
||||
visible: rotateGizmo.dragging
|
||||
parent: rotateGizmo.view3D
|
||||
z: 3
|
||||
|
||||
Text {
|
||||
id: rotateGizmoLabelText
|
||||
text: {
|
||||
// This is skipped during application shutdown, as calling QQuickText::setText()
|
||||
// during application shutdown can crash the application.
|
||||
if (shuttingDown)
|
||||
return text;
|
||||
var l = Qt.locale();
|
||||
if (rotateGizmo.targetNode) {
|
||||
var degrees = rotateGizmo.currentAngle * (180 / Math.PI);
|
||||
return Number(degrees).toLocaleString(l, 'f', 1);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: lightGizmoLabel
|
||||
color: "white"
|
||||
x: lightGizmo.currentMousePos.x - (10 + width)
|
||||
y: lightGizmo.currentMousePos.y - (10 + height)
|
||||
width: lightGizmoLabelText.width + 4
|
||||
height: lightGizmoLabelText.height + 4
|
||||
border.width: 1
|
||||
visible: lightGizmo.dragging
|
||||
parent: lightGizmo.view3D
|
||||
z: 3
|
||||
|
||||
Text {
|
||||
id: lightGizmoLabelText
|
||||
text: lightGizmo.currentLabel
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
|
||||
EditCameraController {
|
||||
id: cameraControl
|
||||
camera: viewRoot.editView ? viewRoot.editView.camera : null
|
||||
anchors.fill: parent
|
||||
view3d: viewRoot.editView
|
||||
sceneId: viewRoot.sceneId
|
||||
}
|
||||
}
|
||||
|
||||
AxisHelper {
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
width: 100
|
||||
height: width
|
||||
editCameraCtrl: cameraControl
|
||||
selectedNode : viewRoot.selectedNodes.length ? selectionBoxes[0].model : null
|
||||
}
|
||||
|
||||
Text {
|
||||
id: sceneLabel
|
||||
text: viewRoot.sceneId
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.margins: 4
|
||||
font.pixelSize: 14
|
||||
color: "white"
|
||||
}
|
||||
|
||||
Text {
|
||||
id: fpsLabel
|
||||
text: viewRoot.fps
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.margins: 4
|
||||
font.pixelSize: 12
|
||||
color: "white"
|
||||
visible: viewRoot.fps > 0
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
|
||||
DirectionalDraggable {
|
||||
id: handleRoot
|
||||
|
||||
property string currentLabel
|
||||
property point currentMousePos
|
||||
property real fadeScale
|
||||
property real baseScale: 5
|
||||
property real dragScale: 1
|
||||
|
||||
scale: autoScaler.getScale(Qt.vector3d(baseScale, baseScale, baseScale))
|
||||
length: 3
|
||||
offset: -1.5
|
||||
|
||||
Model {
|
||||
id: handle
|
||||
source: "#Sphere"
|
||||
materials: [ handleRoot.material ]
|
||||
scale: Qt.vector3d(0.02, 0.02, 0.02)
|
||||
}
|
||||
|
||||
AutoScaleHelper {
|
||||
id: autoScaler
|
||||
active: handleRoot.active
|
||||
view3D: handleRoot.view3D
|
||||
}
|
||||
|
||||
property real _q // quadratic fade
|
||||
property real _l // linear fade
|
||||
property real _c // constant fade
|
||||
property real _d: 20 // Divisor from fadeScale calc in lightGizmo
|
||||
property real _startScale
|
||||
property real _startFadeScale
|
||||
property string _currentProp
|
||||
|
||||
signal valueCommit(string propName)
|
||||
signal valueChange(string propName)
|
||||
|
||||
function updateFade(relativeDistance, screenPos)
|
||||
{
|
||||
// Solved from fadeScale equation in LightGizmo
|
||||
var newValue = 0;
|
||||
var _x = Math.max(0, (_startFadeScale - (relativeDistance * _startScale)) / 100);
|
||||
|
||||
// Fades capped to range 0-10 because property editor caps them to that range
|
||||
if (_currentProp === "quadraticFade") {
|
||||
if (_x === 0)
|
||||
newValue = 10;
|
||||
else
|
||||
newValue = Math.max(0, Math.min(10, -(_c - _d + (_l * _x)) / (_x * _x)));
|
||||
if (newValue < 0.01)
|
||||
newValue = 0; // To avoid having tiny positive value when UI shows 0.00
|
||||
targetNode.quadraticFade = newValue;
|
||||
} else if (_currentProp === "linearFade") {
|
||||
if (_x === 0)
|
||||
newValue = 10;
|
||||
else
|
||||
newValue = Math.max(0, Math.min(10, -(_c - _d) / _x));
|
||||
if (newValue < 0.01)
|
||||
newValue = 0; // To avoid having tiny positive value when UI shows 0.00
|
||||
targetNode.linearFade = newValue;
|
||||
} else {
|
||||
// Since pure constant fade equates to infinitely long cone, fadeScale calc assumes
|
||||
// linear fade of one in this case.
|
||||
newValue = Math.max(0, Math.min(10, _d - _x));
|
||||
targetNode.constantFade = newValue;
|
||||
}
|
||||
|
||||
var l = Qt.locale();
|
||||
handleRoot.currentLabel = _currentProp + qsTr(": ") + Number(newValue).toLocaleString(l, 'f', 2);
|
||||
handleRoot.currentMousePos = screenPos;
|
||||
}
|
||||
|
||||
onPressed: (mouseArea, screenPos)=> {
|
||||
_startScale = autoScaler.relativeScale * baseScale * dragScale;
|
||||
_startFadeScale = fadeScale;
|
||||
_l = targetNode.linearFade;
|
||||
_c = targetNode.constantFade;
|
||||
_q = targetNode.quadraticFade;
|
||||
if (targetNode.quadraticFade === 0) {
|
||||
if (targetNode.linearFade === 0) {
|
||||
_currentProp = "constantFade";
|
||||
} else {
|
||||
_currentProp = "linearFade";
|
||||
}
|
||||
} else {
|
||||
_currentProp = "quadraticFade";
|
||||
}
|
||||
updateFade(0, screenPos);
|
||||
}
|
||||
|
||||
onDragged: (mouseArea, sceneRelativeDistance, relativeDistance, screenPos)=> {
|
||||
updateFade(relativeDistance, screenPos);
|
||||
handleRoot.valueChange(_currentProp);
|
||||
}
|
||||
|
||||
onReleased: (mouseArea, sceneRelativeDistance, relativeDistance, screenPos)=> {
|
||||
updateFade(relativeDistance, screenPos);
|
||||
handleRoot.valueCommit(_currentProp);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
import GridGeometry 1.0
|
||||
|
||||
Node {
|
||||
id: grid
|
||||
|
||||
property alias lines: gridGeometry.lines
|
||||
property alias step: gridGeometry.step
|
||||
property alias subdivAlpha: subGridMaterial.opacity
|
||||
|
||||
eulerRotation.x: 90
|
||||
|
||||
// Note: Only one instance of HelperGrid is supported, as the geometry names are fixed
|
||||
|
||||
Model { // Main grid lines
|
||||
geometry: GridGeometry {
|
||||
id: gridGeometry
|
||||
name: "3D Edit View Helper Grid"
|
||||
}
|
||||
|
||||
materials: [
|
||||
DefaultMaterial {
|
||||
id: mainGridMaterial
|
||||
diffuseColor: "#aaaaaa"
|
||||
lighting: DefaultMaterial.NoLighting
|
||||
cullMode: Material.NoCulling
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Model { // Subdivision lines
|
||||
geometry: GridGeometry {
|
||||
lines: gridGeometry.lines
|
||||
step: gridGeometry.step
|
||||
isSubdivision: true
|
||||
name: "3D Edit View Helper Grid subdivisions"
|
||||
}
|
||||
|
||||
materials: [
|
||||
DefaultMaterial {
|
||||
id: subGridMaterial
|
||||
diffuseColor: mainGridMaterial.diffuseColor
|
||||
lighting: DefaultMaterial.NoLighting
|
||||
cullMode: Material.NoCulling
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Model { // Z Axis
|
||||
geometry: GridGeometry {
|
||||
lines: gridGeometry.lines
|
||||
step: gridGeometry.step
|
||||
isCenterLine: true
|
||||
name: "3D Edit View Helper Grid Z Axis"
|
||||
}
|
||||
materials: [
|
||||
DefaultMaterial {
|
||||
id: vCenterLineMaterial
|
||||
diffuseColor: "#00a1d2"
|
||||
lighting: DefaultMaterial.NoLighting
|
||||
cullMode: Material.NoCulling
|
||||
}
|
||||
]
|
||||
}
|
||||
Model { // X Axis
|
||||
eulerRotation.z: 90
|
||||
geometry: GridGeometry {
|
||||
lines: gridGeometry.lines
|
||||
step: gridGeometry.step
|
||||
isCenterLine: true
|
||||
name: "3D Edit View Helper Grid X Axis"
|
||||
}
|
||||
materials: [
|
||||
DefaultMaterial {
|
||||
id: hCenterLineMaterial
|
||||
diffuseColor: "#cb211a"
|
||||
lighting: DefaultMaterial.NoLighting
|
||||
cullMode: Material.NoCulling
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
|
||||
Item {
|
||||
id: iconGizmo
|
||||
|
||||
property Node activeScene: null
|
||||
property Node scene: null
|
||||
property View3D view3D
|
||||
property bool highlightOnHover: true
|
||||
property Node targetNode: null
|
||||
property var selectedNodes: []
|
||||
readonly property bool selected: {
|
||||
for (var i = 0; i < selectedNodes.length; ++i) {
|
||||
if (selectedNodes[i] === targetNode)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
property bool hasMouse: false
|
||||
property bool hidden: false
|
||||
property bool locked: false
|
||||
|
||||
property alias iconSource: iconImage.source
|
||||
|
||||
signal clicked(Node node, bool multi)
|
||||
|
||||
onSelectedChanged: {
|
||||
if (selected)
|
||||
hasMouse = false;
|
||||
}
|
||||
|
||||
visible: activeScene === scene && !hidden && (targetNode ? targetNode.visible : false)
|
||||
|
||||
Overlay2D {
|
||||
id: iconOverlay
|
||||
targetNode: iconGizmo.targetNode
|
||||
targetView: view3D
|
||||
visible: iconGizmo.visible && !isBehindCamera
|
||||
|
||||
Rectangle {
|
||||
id: iconRect
|
||||
|
||||
width: iconImage.width
|
||||
height: iconImage.height
|
||||
x: -width / 2
|
||||
y: -height / 2
|
||||
color: "transparent"
|
||||
border.color: "#7777ff"
|
||||
border.width: !iconGizmo.locked && iconGizmo.highlightOnHover && iconGizmo.hasMouse ? 2 : 0
|
||||
radius: 5
|
||||
opacity: iconGizmo.selected ? 0.2 : 1
|
||||
Image {
|
||||
id: iconImage
|
||||
fillMode: Image.Pad
|
||||
MouseArea {
|
||||
id: iconMouseArea
|
||||
anchors.fill: parent
|
||||
onPressed: (mouse)=> {
|
||||
// Ignore singleselection mouse presses when we have single object selected
|
||||
// so that the icon gizmo doesn't hijack mouse clicks meant for other gizmos
|
||||
if (iconGizmo.selected && !(mouse.modifiers & Qt.ControlModifier)
|
||||
&& selectedNodes.length === 1) {
|
||||
mouse.accepted = false;
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: (mouse)=> {
|
||||
iconGizmo.clicked(iconGizmo.targetNode,
|
||||
mouse.modifiers & Qt.ControlModifier);
|
||||
}
|
||||
hoverEnabled: iconGizmo.highlightOnHover && !iconGizmo.selected
|
||||
acceptedButtons: Qt.LeftButton
|
||||
|
||||
// onPositionChanged, onContainsMouseAreaChanged, and hasMouse are used instead
|
||||
// of just using containsMouse directly, because containsMouse
|
||||
// cannot be relied upon to update correctly in some situations.
|
||||
// This is likely because the overlapping 3D mouse areas of the gizmos get
|
||||
// the mouse events instead of this area, so mouse leaving the area
|
||||
// doesn't always update containsMouse property.
|
||||
onPositionChanged: {
|
||||
if (!iconGizmo.selected)
|
||||
iconGizmo.hasMouse = containsMouse;
|
||||
}
|
||||
|
||||
onContainsMouseChanged: {
|
||||
if (!iconGizmo.selected)
|
||||
iconGizmo.hasMouse = containsMouse;
|
||||
else
|
||||
iconGizmo.hasMouse = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
|
||||
Item {
|
||||
id: viewRoot
|
||||
width: 1024
|
||||
height: 1024
|
||||
visible: true
|
||||
|
||||
property alias view3D: view3D
|
||||
property alias camPos: viewCamera.position
|
||||
|
||||
function setSceneToBox()
|
||||
{
|
||||
selectionBox.targetNode = view3D.importScene;
|
||||
}
|
||||
|
||||
function fitAndHideBox()
|
||||
{
|
||||
cameraControl.focusObject(selectionBox.model, viewCamera.eulerRotation, true, true);
|
||||
if (cameraControl._zoomFactor < 0.1)
|
||||
view3D.importScene.scale = view3D.importScene.scale.times(10);
|
||||
if (cameraControl._zoomFactor > 10)
|
||||
view3D.importScene.scale = view3D.importScene.scale.times(0.1);
|
||||
|
||||
selectionBox.visible = false;
|
||||
}
|
||||
|
||||
View3D {
|
||||
id: view3D
|
||||
camera: viewCamera
|
||||
environment: sceneEnv
|
||||
|
||||
SceneEnvironment {
|
||||
id: sceneEnv
|
||||
antialiasingMode: SceneEnvironment.MSAA
|
||||
antialiasingQuality: SceneEnvironment.VeryHigh
|
||||
}
|
||||
|
||||
PerspectiveCamera {
|
||||
id: viewCamera
|
||||
position: Qt.vector3d(-200, 200, 200)
|
||||
eulerRotation: Qt.vector3d(-45, -45, 0)
|
||||
}
|
||||
|
||||
DirectionalLight {
|
||||
rotation: viewCamera.rotation
|
||||
}
|
||||
|
||||
SelectionBox {
|
||||
id: selectionBox
|
||||
view3D: view3D
|
||||
geometryName: "SB"
|
||||
}
|
||||
|
||||
EditCameraController {
|
||||
id: cameraControl
|
||||
camera: view3D.camera
|
||||
view3d: view3D
|
||||
ignoreToolState: true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,356 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
import MouseArea3D 1.0
|
||||
import LightUtils 1.0
|
||||
|
||||
Node {
|
||||
id: lightGizmo
|
||||
|
||||
property View3D view3D
|
||||
property Node targetNode: null
|
||||
property MouseArea3D dragHelper: null
|
||||
property color color: Qt.rgba(1, 1, 0, 1)
|
||||
property real fadeScale: {
|
||||
// Value indicates area where intensity is above certain percent of total brightness.
|
||||
if (lightGizmo.targetNode instanceof SpotLight || lightGizmo.targetNode instanceof PointLight) {
|
||||
var l = targetNode.linearFade;
|
||||
var q = targetNode.quadraticFade;
|
||||
var c = targetNode.constantFade;
|
||||
var d = 20; // divisor to target intensity value. E.g. 20 = 1/20 = 5%
|
||||
if (l === 0 && q === 0)
|
||||
l = 1; // For pure constant fade, cone would be infinite, so pretend we have linear fade
|
||||
// Solved from equation in shader:
|
||||
// 1 / d = 1 / (c + (l + q * dist) * dist);
|
||||
if (q === 0)
|
||||
return 100 * Math.max(((d - c) / l), 1);
|
||||
else
|
||||
return 100 * ((Math.sqrt(4 * q * (d - c) + (l * l)) - l) / (2 * q));
|
||||
} else {
|
||||
return 100;
|
||||
}
|
||||
}
|
||||
readonly property bool dragging: primaryArrow.dragging
|
||||
|| spotLightHandle.dragging
|
||||
|| spotLightInnerHandle.dragging
|
||||
|| spotLightFadeHandle.dragging
|
||||
|| areaHeightHandle.dragging
|
||||
|| areaWidthHandle.dragging
|
||||
|| pointLightFadeHandle.dragging
|
||||
property point currentMousePos
|
||||
property string currentLabel
|
||||
property int brightnessDecimals: _generalHelper.brightnessScaler() > 10. ? 0 : 2;
|
||||
property real brightnessMultiplier: Math.pow(10, brightnessDecimals);
|
||||
|
||||
signal propertyValueCommit(string propName)
|
||||
signal propertyValueChange(string propName)
|
||||
|
||||
position: targetNode ? targetNode.scenePosition : Qt.vector3d(0, 0, 0)
|
||||
visible: lightGizmo.targetNode instanceof SpotLight
|
||||
|| lightGizmo.targetNode instanceof AreaLight
|
||||
|| lightGizmo.targetNode instanceof DirectionalLight
|
||||
|| lightGizmo.targetNode instanceof PointLight
|
||||
|
||||
AutoScaleHelper {
|
||||
id: autoScaler
|
||||
view3D: lightGizmo.view3D
|
||||
}
|
||||
|
||||
Node {
|
||||
id: pointLightParts
|
||||
rotation: lightGizmo.view3D.camera.rotation
|
||||
visible: lightGizmo.targetNode instanceof PointLight
|
||||
|
||||
LightModel {
|
||||
id: pointModel
|
||||
geometryName: "Edit 3D PointLight"
|
||||
geometryType: LightGeometry.Point
|
||||
material: lightMaterial
|
||||
scale: Qt.vector3d(lightGizmo.fadeScale, lightGizmo.fadeScale, lightGizmo.fadeScale)
|
||||
}
|
||||
|
||||
FadeHandle {
|
||||
id: pointLightFadeHandle
|
||||
view3D: lightGizmo.view3D
|
||||
color: (hovering || dragging) ? Qt.rgba(1, 1, 1, 1) : lightGizmo.color
|
||||
position: lightGizmo.targetNode instanceof PointLight ? Qt.vector3d(-pointModel.scale.x, 0, 0)
|
||||
: Qt.vector3d(0, 0, 0)
|
||||
eulerRotation: Qt.vector3d(0, 0, -90)
|
||||
targetNode: lightGizmo.targetNode instanceof PointLight ? lightGizmo.targetNode : null
|
||||
active: lightGizmo.targetNode instanceof PointLight
|
||||
dragHelper: lightGizmo.dragHelper
|
||||
fadeScale: lightGizmo.fadeScale
|
||||
|
||||
onCurrentMousePosChanged: {
|
||||
lightGizmo.currentMousePos = currentMousePos;
|
||||
lightGizmo.currentLabel = currentLabel;
|
||||
}
|
||||
onValueChange: (propName)=> {
|
||||
lightGizmo.propertyValueChange(propName);
|
||||
}
|
||||
onValueCommit: (propName)=> {
|
||||
lightGizmo.propertyValueCommit(propName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Node {
|
||||
rotation: !lightGizmo.targetNode ? Qt.quaternion(1, 0, 0, 0)
|
||||
: lightGizmo.targetNode.sceneRotation
|
||||
|
||||
Node {
|
||||
id: spotParts
|
||||
visible: lightGizmo.targetNode instanceof SpotLight
|
||||
|
||||
LightModel {
|
||||
id: spotModel
|
||||
|
||||
property real coneXYScale: spotParts.visible && lightGizmo.targetNode
|
||||
? lightGizmo.fadeScale * Math.tan(Math.PI * lightGizmo.targetNode.coneAngle / 180)
|
||||
: 1
|
||||
|
||||
geometryName: "Edit 3D SpotLight Cone"
|
||||
geometryType: LightGeometry.Spot
|
||||
material: lightMaterial
|
||||
scale: Qt.vector3d(coneXYScale, coneXYScale,
|
||||
spotParts.visible && lightGizmo.targetNode && lightGizmo.targetNode.coneAngle > 90
|
||||
? -lightGizmo.fadeScale : lightGizmo.fadeScale)
|
||||
}
|
||||
|
||||
LightModel {
|
||||
id: spotInnerModel
|
||||
|
||||
property real coneXYScale: spotParts.visible && lightGizmo.targetNode
|
||||
? lightGizmo.fadeScale * Math.tan(Math.PI * lightGizmo.targetNode.innerConeAngle / 180)
|
||||
: 1
|
||||
|
||||
geometryName: "Edit 3D SpotLight Inner Cone"
|
||||
geometryType: LightGeometry.Spot
|
||||
material: lightMaterial
|
||||
scale: Qt.vector3d(coneXYScale, coneXYScale,
|
||||
spotParts.visible && lightGizmo.targetNode && lightGizmo.targetNode.innerConeAngle > 90
|
||||
? -lightGizmo.fadeScale : lightGizmo.fadeScale)
|
||||
}
|
||||
|
||||
SpotLightHandle {
|
||||
id: spotLightHandle
|
||||
view3D: lightGizmo.view3D
|
||||
color: (hovering || dragging) ? Qt.rgba(1, 1, 1, 1) : lightGizmo.color
|
||||
position: lightGizmo.targetNode instanceof SpotLight ? Qt.vector3d(0, spotModel.scale.y, -spotModel.scale.z)
|
||||
: Qt.vector3d(0, 0, 0)
|
||||
targetNode: lightGizmo.targetNode instanceof SpotLight ? lightGizmo.targetNode : null
|
||||
active: lightGizmo.targetNode instanceof SpotLight
|
||||
dragHelper: lightGizmo.dragHelper
|
||||
propName: "coneAngle"
|
||||
propValue: lightGizmo.targetNode instanceof SpotLight ? targetNode.coneAngle : 0
|
||||
|
||||
onNewValueChanged: targetNode.coneAngle = newValue
|
||||
onCurrentMousePosChanged: {
|
||||
lightGizmo.currentMousePos = currentMousePos;
|
||||
lightGizmo.currentLabel = currentLabel;
|
||||
}
|
||||
onValueChange: lightGizmo.propertyValueChange(propName)
|
||||
onValueCommit: {
|
||||
if (targetNode.innerConeAngle > targetNode.coneAngle)
|
||||
targetNode.innerConeAngle = targetNode.coneAngle;
|
||||
lightGizmo.propertyValueCommit(propName)
|
||||
lightGizmo.propertyValueCommit(spotLightInnerHandle.propName);
|
||||
}
|
||||
}
|
||||
|
||||
SpotLightHandle {
|
||||
id: spotLightInnerHandle
|
||||
view3D: lightGizmo.view3D
|
||||
color: (hovering || dragging) ? Qt.rgba(1, 1, 1, 1) : lightGizmo.color
|
||||
position: lightGizmo.targetNode instanceof SpotLight ? Qt.vector3d(0, -spotInnerModel.scale.y, -spotInnerModel.scale.z)
|
||||
: Qt.vector3d(0, 0, 0)
|
||||
eulerRotation: Qt.vector3d(180, 0, 0)
|
||||
targetNode: lightGizmo.targetNode instanceof SpotLight ? lightGizmo.targetNode : null
|
||||
active: lightGizmo.targetNode instanceof SpotLight
|
||||
dragHelper: lightGizmo.dragHelper
|
||||
propName: "innerConeAngle"
|
||||
propValue: lightGizmo.targetNode instanceof SpotLight ? targetNode.innerConeAngle : 0
|
||||
|
||||
onNewValueChanged: targetNode.innerConeAngle = newValue
|
||||
onCurrentMousePosChanged: {
|
||||
lightGizmo.currentMousePos = currentMousePos;
|
||||
lightGizmo.currentLabel = currentLabel;
|
||||
}
|
||||
onValueChange: lightGizmo.propertyValueChange(propName)
|
||||
onValueCommit: {
|
||||
if (targetNode.coneAngle < targetNode.innerConeAngle)
|
||||
targetNode.coneAngle = targetNode.innerConeAngle;
|
||||
lightGizmo.propertyValueCommit(propName)
|
||||
lightGizmo.propertyValueCommit(spotLightHandle.propName);
|
||||
}
|
||||
}
|
||||
|
||||
FadeHandle {
|
||||
id: spotLightFadeHandle
|
||||
view3D: lightGizmo.view3D
|
||||
color: (hovering || dragging) ? Qt.rgba(1, 1, 1, 1) : lightGizmo.color
|
||||
position: lightGizmo.targetNode instanceof SpotLight ? Qt.vector3d(spotModel.scale.x / 2, 0, -spotInnerModel.scale.z / 2)
|
||||
: Qt.vector3d(0, 0, 0)
|
||||
eulerRotation: Qt.vector3d(90, 0, 0)
|
||||
targetNode: lightGizmo.targetNode instanceof SpotLight ? lightGizmo.targetNode : null
|
||||
active: lightGizmo.targetNode instanceof SpotLight
|
||||
dragHelper: lightGizmo.dragHelper
|
||||
fadeScale: lightGizmo.fadeScale
|
||||
dragScale: 2
|
||||
|
||||
onCurrentMousePosChanged: {
|
||||
lightGizmo.currentMousePos = currentMousePos;
|
||||
lightGizmo.currentLabel = currentLabel;
|
||||
}
|
||||
onValueChange: (propName)=> {
|
||||
lightGizmo.propertyValueChange(propName);
|
||||
}
|
||||
onValueCommit: (propName)=> {
|
||||
lightGizmo.propertyValueCommit(propName);
|
||||
}
|
||||
}
|
||||
}
|
||||
Node {
|
||||
id: areaParts
|
||||
visible: lightGizmo.targetNode instanceof AreaLight
|
||||
|
||||
LightModel {
|
||||
id: areaModel
|
||||
geometryName: "Edit 3D AreaLight"
|
||||
geometryType: LightGeometry.Area
|
||||
material: lightMaterial
|
||||
scale: areaParts.visible ? Qt.vector3d(lightGizmo.targetNode.width / 2,
|
||||
lightGizmo.targetNode.height / 2, 1)
|
||||
.times(lightGizmo.targetNode.scale)
|
||||
: Qt.vector3d(1, 1, 1)
|
||||
}
|
||||
|
||||
AreaLightHandle {
|
||||
id: areaWidthHandle
|
||||
view3D: lightGizmo.view3D
|
||||
color: (hovering || dragging) ? Qt.rgba(1, 1, 1, 1) : lightGizmo.color
|
||||
position: lightGizmo.targetNode instanceof AreaLight ? Qt.vector3d(-areaModel.scale.x, 0, 0)
|
||||
: Qt.vector3d(0, 0, 0)
|
||||
eulerRotation: Qt.vector3d(0, 0, 90)
|
||||
targetNode: lightGizmo.targetNode instanceof AreaLight ? lightGizmo.targetNode : null
|
||||
active: lightGizmo.targetNode instanceof AreaLight
|
||||
dragHelper: lightGizmo.dragHelper
|
||||
propName: "width"
|
||||
propValue: lightGizmo.targetNode instanceof AreaLight ? targetNode.width : 0
|
||||
|
||||
onNewValueChanged: targetNode.width = newValue
|
||||
onCurrentMousePosChanged: {
|
||||
lightGizmo.currentMousePos = currentMousePos;
|
||||
lightGizmo.currentLabel = currentLabel;
|
||||
}
|
||||
onValueChange: lightGizmo.propertyValueChange(propName)
|
||||
onValueCommit: lightGizmo.propertyValueCommit(propName)
|
||||
}
|
||||
|
||||
AreaLightHandle {
|
||||
id: areaHeightHandle
|
||||
view3D: lightGizmo.view3D
|
||||
color: (hovering || dragging) ? Qt.rgba(1, 1, 1, 1) : lightGizmo.color
|
||||
position: lightGizmo.targetNode instanceof AreaLight ? Qt.vector3d(0, -areaModel.scale.y, 0)
|
||||
: Qt.vector3d(0, 0, 0)
|
||||
eulerRotation: Qt.vector3d(0, 0, 180)
|
||||
targetNode: lightGizmo.targetNode instanceof AreaLight ? lightGizmo.targetNode : null
|
||||
active: lightGizmo.targetNode instanceof AreaLight
|
||||
dragHelper: lightGizmo.dragHelper
|
||||
propName: "height"
|
||||
propValue: lightGizmo.targetNode instanceof AreaLight ? targetNode.height : 0
|
||||
|
||||
onNewValueChanged: targetNode.height = newValue
|
||||
onCurrentMousePosChanged: {
|
||||
lightGizmo.currentMousePos = currentMousePos;
|
||||
lightGizmo.currentLabel = currentLabel;
|
||||
}
|
||||
onValueChange: lightGizmo.propertyValueChange(propName)
|
||||
onValueCommit: lightGizmo.propertyValueCommit(propName)
|
||||
}
|
||||
}
|
||||
|
||||
LightModel {
|
||||
id: directionalModel
|
||||
geometryName: "Edit 3D DirLight"
|
||||
geometryType: LightGeometry.Directional
|
||||
material: lightMaterial
|
||||
visible: lightGizmo.targetNode instanceof DirectionalLight
|
||||
scale: autoScaler.getScale(Qt.vector3d(50, 50, 50))
|
||||
}
|
||||
|
||||
AdjustableArrow {
|
||||
id: primaryArrow
|
||||
eulerRotation: Qt.vector3d(-90, 0, 0)
|
||||
targetNode: lightGizmo.targetNode
|
||||
color: (hovering || dragging) ? Qt.rgba(1, 1, 1, 1) : lightGizmo.color
|
||||
view3D: lightGizmo.view3D
|
||||
active: lightGizmo.visible
|
||||
dragHelper: lightGizmo.dragHelper
|
||||
scale: autoScaler.getScale(Qt.vector3d(5, 5, 5))
|
||||
length: targetNode ? Math.max(1.0, 1.0 + targetNode.brightness / _generalHelper.brightnessScaler() * 10.0) + 3 : 10
|
||||
|
||||
property real _startBrightness
|
||||
|
||||
function updateBrightness(relativeDistance, screenPos)
|
||||
{
|
||||
var currentValue = Math.max(0, (_startBrightness + relativeDistance * _generalHelper.brightnessScaler() / 10.0));
|
||||
currentValue *= brightnessMultiplier;
|
||||
currentValue = Math.round(currentValue);
|
||||
currentValue /= brightnessMultiplier;
|
||||
|
||||
var l = Qt.locale();
|
||||
lightGizmo.currentLabel = "brightness" + qsTr(": ") + Number(currentValue).toLocaleString(l, 'f', brightnessDecimals);
|
||||
lightGizmo.currentMousePos = screenPos;
|
||||
targetNode.brightness = currentValue;
|
||||
}
|
||||
|
||||
onPressed: (mouseArea, screenPos)=> {
|
||||
_startBrightness = targetNode.brightness;
|
||||
updateBrightness(0, screenPos);
|
||||
}
|
||||
|
||||
onDragged: (mouseArea, sceneRelativeDistance, relativeDistance, screenPos)=> {
|
||||
updateBrightness(relativeDistance, screenPos);
|
||||
lightGizmo.propertyValueChange("brightness");
|
||||
}
|
||||
|
||||
onReleased: (mouseArea, sceneRelativeDistance, relativeDistance, screenPos)=> {
|
||||
updateBrightness(relativeDistance, screenPos);
|
||||
lightGizmo.propertyValueCommit("brightness");
|
||||
}
|
||||
}
|
||||
|
||||
DefaultMaterial {
|
||||
id: lightMaterial
|
||||
diffuseColor: lightGizmo.color
|
||||
lighting: DefaultMaterial.NoLighting
|
||||
cullMode: Material.NoCulling
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
import LightUtils 1.0
|
||||
|
||||
IconGizmo {
|
||||
id: lightIconGizmo
|
||||
|
||||
property color overlayColor: targetNode ? targetNode.color : "transparent"
|
||||
|
||||
iconSource: targetNode
|
||||
? targetNode instanceof DirectionalLight
|
||||
? "image://IconGizmoImageProvider/directional.png:" + overlayColor
|
||||
: targetNode instanceof AreaLight
|
||||
? "image://IconGizmoImageProvider/area.png:" + overlayColor
|
||||
: targetNode instanceof PointLight
|
||||
? "image://IconGizmoImageProvider/point.png:" + overlayColor
|
||||
: "image://IconGizmoImageProvider/spot.png:" + overlayColor
|
||||
: "image://IconGizmoImageProvider/point.png:" + overlayColor
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
import LightUtils 1.0
|
||||
|
||||
Model {
|
||||
id: lightModel
|
||||
|
||||
property alias geometryName: lightGeometry.name // Name must be unique for each geometry
|
||||
property alias geometryType: lightGeometry.lightType
|
||||
property Material material
|
||||
|
||||
function updateGeometry()
|
||||
{
|
||||
lightGeometry.update();
|
||||
}
|
||||
|
||||
scale: Qt.vector3d(50, 50, 50)
|
||||
|
||||
geometry: lightGeometry
|
||||
materials: [ material ]
|
||||
|
||||
LightGeometry {
|
||||
id: lightGeometry
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
import LineGeometry 1.0
|
||||
|
||||
Node {
|
||||
id: pivotLine
|
||||
|
||||
property alias startPos: lineGeometry.startPos
|
||||
property alias endPos: lineGeometry.endPos
|
||||
property alias name: lineGeometry.name // Name must be unique for each line
|
||||
property alias color: lineMat.diffuseColor
|
||||
|
||||
Model {
|
||||
geometry: LineGeometry {
|
||||
id: lineGeometry
|
||||
}
|
||||
materials: [
|
||||
DefaultMaterial {
|
||||
id: lineMat
|
||||
lighting: DefaultMaterial.NoLighting
|
||||
cullMode: Material.NoCulling
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 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 QtQuick3D 6.0
|
||||
|
||||
View3D {
|
||||
id: root
|
||||
anchors.fill: parent
|
||||
environment: sceneEnv
|
||||
|
||||
property Material previewMaterial
|
||||
|
||||
SceneEnvironment {
|
||||
id: sceneEnv
|
||||
antialiasingMode: SceneEnvironment.MSAA
|
||||
antialiasingQuality: SceneEnvironment.High
|
||||
}
|
||||
|
||||
Node {
|
||||
DirectionalLight {
|
||||
eulerRotation.x: -30
|
||||
eulerRotation.y: -30
|
||||
}
|
||||
|
||||
PerspectiveCamera {
|
||||
z: 120
|
||||
clipFar: 1000
|
||||
clipNear: 1
|
||||
}
|
||||
|
||||
Model {
|
||||
id: model
|
||||
source: "#Sphere"
|
||||
materials: previewMaterial
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 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 6.0
|
||||
|
||||
Item {
|
||||
id: root
|
||||
width: 150
|
||||
height: 150
|
||||
|
||||
property alias contentItem: contentItem
|
||||
|
||||
/*
|
||||
View3D {
|
||||
// Dummy view to hold the context in case View3D items are used in the component
|
||||
// TODO remove when QTBUG-87678 is fixed
|
||||
}
|
||||
*/
|
||||
|
||||
Item {
|
||||
id: contentItem
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
|
||||
Item {
|
||||
id: root
|
||||
width: 150
|
||||
height: 150
|
||||
visible: true
|
||||
|
||||
property View3D view: null
|
||||
property alias contentItem: contentItem
|
||||
|
||||
property var previewObject
|
||||
|
||||
property var materialViewComponent
|
||||
property var modelViewComponent
|
||||
property var nodeViewComponent
|
||||
|
||||
property bool ready: false
|
||||
|
||||
function destroyView()
|
||||
{
|
||||
previewObject = null;
|
||||
if (view)
|
||||
view.destroy();
|
||||
}
|
||||
|
||||
function createViewForObject(obj)
|
||||
{
|
||||
if (obj instanceof Material)
|
||||
createViewForMaterial(obj);
|
||||
else if (obj instanceof Model)
|
||||
createViewForModel(obj);
|
||||
else if (obj instanceof Node)
|
||||
createViewForNode(obj);
|
||||
|
||||
previewObject = obj;
|
||||
}
|
||||
|
||||
function createViewForMaterial(material)
|
||||
{
|
||||
if (!materialViewComponent)
|
||||
materialViewComponent = Qt.createComponent("MaterialNodeView.qml");
|
||||
|
||||
// Always recreate the view to ensure material is up to date
|
||||
if (materialViewComponent.status === Component.Ready)
|
||||
view = materialViewComponent.createObject(viewRect, {"previewMaterial": material});
|
||||
}
|
||||
|
||||
function createViewForModel(model)
|
||||
{
|
||||
if (!modelViewComponent)
|
||||
modelViewComponent = Qt.createComponent("ModelNodeView.qml");
|
||||
|
||||
// Always recreate the view to ensure model is up to date
|
||||
if (modelViewComponent.status === Component.Ready)
|
||||
view = modelViewComponent.createObject(viewRect, {"sourceModel": model});
|
||||
}
|
||||
|
||||
function createViewForNode(node)
|
||||
{
|
||||
if (!nodeViewComponent)
|
||||
nodeViewComponent = Qt.createComponent("NodeNodeView.qml");
|
||||
|
||||
// Always recreate the view to ensure node is up to date
|
||||
if (nodeViewComponent.status === Component.Ready)
|
||||
view = nodeViewComponent.createObject(viewRect, {"importScene": node});
|
||||
}
|
||||
|
||||
function afterRender()
|
||||
{
|
||||
if (previewObject instanceof Node) {
|
||||
view.fitToViewPort();
|
||||
ready = view.ready;
|
||||
} else {
|
||||
ready = true;
|
||||
}
|
||||
}
|
||||
|
||||
View3D {
|
||||
// Dummy view to hold the context
|
||||
// TODO remove when QTBUG-87678 is fixed
|
||||
}
|
||||
|
||||
Item {
|
||||
id: contentItem
|
||||
anchors.fill: parent
|
||||
|
||||
Rectangle {
|
||||
id: viewRect
|
||||
anchors.fill: parent
|
||||
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 1.0; color: "#222222" }
|
||||
GradientStop { position: 0.0; color: "#999999" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
|
||||
View3D {
|
||||
id: root
|
||||
anchors.fill: parent
|
||||
environment: sceneEnv
|
||||
camera: theCamera
|
||||
|
||||
property bool ready: false
|
||||
property real prevZoomFactor: -1
|
||||
property Model sourceModel
|
||||
|
||||
function fitToViewPort()
|
||||
{
|
||||
cameraControl.focusObject(model, theCamera.eulerRotation, true, false);
|
||||
|
||||
if (cameraControl._zoomFactor < 0.1) {
|
||||
model.scale = model.scale.times(10);
|
||||
} else if (cameraControl._zoomFactor > 10) {
|
||||
model.scale = model.scale.times(0.1);
|
||||
} else {
|
||||
// We need one more render after zoom factor change, so only set ready when zoom factor
|
||||
// or scaling hasn't changed from the previous frame
|
||||
ready = _generalHelper.fuzzyCompare(cameraControl._zoomFactor, prevZoomFactor);
|
||||
prevZoomFactor = cameraControl._zoomFactor;
|
||||
}
|
||||
}
|
||||
|
||||
SceneEnvironment {
|
||||
id: sceneEnv
|
||||
antialiasingMode: SceneEnvironment.MSAA
|
||||
antialiasingQuality: SceneEnvironment.High
|
||||
}
|
||||
|
||||
EditCameraController {
|
||||
id: cameraControl
|
||||
camera: theCamera
|
||||
anchors.fill: parent
|
||||
view3d: root
|
||||
ignoreToolState: true
|
||||
}
|
||||
|
||||
DirectionalLight {
|
||||
eulerRotation.x: -30
|
||||
eulerRotation.y: -30
|
||||
}
|
||||
|
||||
PerspectiveCamera {
|
||||
id: theCamera
|
||||
z: 600
|
||||
y: 600
|
||||
eulerRotation.x: -45
|
||||
clipFar: 10000
|
||||
clipNear: 1
|
||||
}
|
||||
|
||||
Model {
|
||||
id: model
|
||||
eulerRotation.y: 45
|
||||
|
||||
source: sourceModel.source
|
||||
geometry: sourceModel.geometry
|
||||
|
||||
materials: [
|
||||
DefaultMaterial {
|
||||
diffuseColor: "#4aee45"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
import MouseArea3D 1.0
|
||||
|
||||
Node {
|
||||
id: moveGizmo
|
||||
|
||||
property View3D view3D
|
||||
property bool highlightOnHover: false
|
||||
property Node targetNode: null
|
||||
property bool globalOrientation: true
|
||||
readonly property bool dragging: arrowX.dragging || arrowY.dragging || arrowZ.dragging
|
||||
|| planeX.dragging || planeY.dragging || planeZ.dragging
|
||||
|| centerBall.dragging
|
||||
property MouseArea3D dragHelper: null
|
||||
property alias freeDraggerArea: centerBall.mouseArea
|
||||
|
||||
position: dragHelper.pivotScenePosition(targetNode)
|
||||
|
||||
onTargetNodeChanged: position = dragHelper.pivotScenePosition(targetNode)
|
||||
|
||||
Connections {
|
||||
target: moveGizmo.targetNode
|
||||
function onSceneTransformChanged()
|
||||
{
|
||||
moveGizmo.position = moveGizmo.dragHelper.pivotScenePosition(moveGizmo.targetNode);
|
||||
}
|
||||
}
|
||||
|
||||
signal positionCommit()
|
||||
signal positionMove()
|
||||
|
||||
Node {
|
||||
rotation: globalOrientation || !moveGizmo.targetNode ? Qt.quaternion(1, 0, 0, 0)
|
||||
: moveGizmo.targetNode.sceneRotation
|
||||
Arrow {
|
||||
id: arrowX
|
||||
eulerRotation: Qt.vector3d(0, 0, -90)
|
||||
targetNode: moveGizmo.targetNode
|
||||
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(1, 0, 0, 1))
|
||||
: Qt.rgba(1, 0, 0, 1)
|
||||
view3D: moveGizmo.view3D
|
||||
active: moveGizmo.visible
|
||||
dragHelper: moveGizmo.dragHelper
|
||||
|
||||
onPositionCommit: moveGizmo.positionCommit()
|
||||
onPositionMove: moveGizmo.positionMove()
|
||||
}
|
||||
|
||||
Arrow {
|
||||
id: arrowY
|
||||
eulerRotation: Qt.vector3d(0, 0, 0)
|
||||
targetNode: moveGizmo.targetNode
|
||||
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0, 0.6, 0, 1))
|
||||
: Qt.rgba(0, 0.6, 0, 1)
|
||||
view3D: moveGizmo.view3D
|
||||
active: moveGizmo.visible
|
||||
dragHelper: moveGizmo.dragHelper
|
||||
|
||||
onPositionCommit: moveGizmo.positionCommit()
|
||||
onPositionMove: moveGizmo.positionMove()
|
||||
}
|
||||
|
||||
Arrow {
|
||||
id: arrowZ
|
||||
eulerRotation: Qt.vector3d(90, 0, 0)
|
||||
targetNode: moveGizmo.targetNode
|
||||
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0, 0, 1, 1))
|
||||
: Qt.rgba(0, 0, 1, 1)
|
||||
view3D: moveGizmo.view3D
|
||||
active: moveGizmo.visible
|
||||
dragHelper: moveGizmo.dragHelper
|
||||
|
||||
onPositionCommit: moveGizmo.positionCommit()
|
||||
onPositionMove: moveGizmo.positionMove()
|
||||
}
|
||||
|
||||
PlanarMoveHandle {
|
||||
id: planeX
|
||||
|
||||
y: 10
|
||||
z: 10
|
||||
|
||||
eulerRotation: Qt.vector3d(0, 90, 0)
|
||||
targetNode: moveGizmo.targetNode
|
||||
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(1, 0, 0, 1))
|
||||
: Qt.rgba(1, 0, 0, 1)
|
||||
view3D: moveGizmo.view3D
|
||||
active: moveGizmo.visible
|
||||
dragHelper: moveGizmo.dragHelper
|
||||
|
||||
onPositionCommit: moveGizmo.positionCommit()
|
||||
onPositionMove: moveGizmo.positionMove()
|
||||
}
|
||||
|
||||
PlanarMoveHandle {
|
||||
id: planeY
|
||||
|
||||
x: 10
|
||||
z: 10
|
||||
|
||||
eulerRotation: Qt.vector3d(90, 0, 0)
|
||||
targetNode: moveGizmo.targetNode
|
||||
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0, 0.6, 0, 1))
|
||||
: Qt.rgba(0, 0.6, 0, 1)
|
||||
view3D: moveGizmo.view3D
|
||||
active: moveGizmo.visible
|
||||
dragHelper: moveGizmo.dragHelper
|
||||
|
||||
onPositionCommit: moveGizmo.positionCommit()
|
||||
onPositionMove: moveGizmo.positionMove()
|
||||
}
|
||||
|
||||
PlanarMoveHandle {
|
||||
id: planeZ
|
||||
|
||||
x: 10
|
||||
y: 10
|
||||
|
||||
eulerRotation: Qt.vector3d(0, 0, 0)
|
||||
targetNode: moveGizmo.targetNode
|
||||
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0, 0, 1, 1))
|
||||
: Qt.rgba(0, 0, 1, 1)
|
||||
view3D: moveGizmo.view3D
|
||||
active: moveGizmo.visible
|
||||
dragHelper: moveGizmo.dragHelper
|
||||
|
||||
onPositionCommit: moveGizmo.positionCommit()
|
||||
onPositionMove: moveGizmo.positionMove()
|
||||
}
|
||||
}
|
||||
|
||||
PlanarMoveHandle {
|
||||
id: centerBall
|
||||
|
||||
source: "#Sphere"
|
||||
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0.5, 0.5, 0.5, 1))
|
||||
: Qt.rgba(0.5, 0.5, 0.5, 1)
|
||||
rotation: view3D.camera.rotation
|
||||
priority: 10
|
||||
targetNode: moveGizmo.targetNode
|
||||
|
||||
view3D: moveGizmo.view3D
|
||||
active: moveGizmo.visible
|
||||
dragHelper: moveGizmo.dragHelper
|
||||
|
||||
onPositionCommit: moveGizmo.positionCommit()
|
||||
onPositionMove: moveGizmo.positionMove()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
|
||||
View3D {
|
||||
id: root
|
||||
anchors.fill: parent
|
||||
environment: sceneEnv
|
||||
camera: theCamera
|
||||
|
||||
property bool ready: false
|
||||
property bool first: true
|
||||
property real prevZoomFactor: -1
|
||||
|
||||
function fitToViewPort()
|
||||
{
|
||||
if (first) {
|
||||
first = false;
|
||||
selectionBox.targetNode = root.importScene;
|
||||
} else {
|
||||
cameraControl.focusObject(selectionBox.model, theCamera.eulerRotation, true, false);
|
||||
|
||||
if (cameraControl._zoomFactor < 0.1) {
|
||||
root.importScene.scale = root.importScene.scale.times(10);
|
||||
} else if (cameraControl._zoomFactor > 10) {
|
||||
root.importScene.scale = root.importScene.scale.times(0.1);
|
||||
} else {
|
||||
// We need one more render after zoom factor change, so only set ready when zoom factor
|
||||
// or scaling hasn't changed from the previous frame
|
||||
ready = _generalHelper.fuzzyCompare(cameraControl._zoomFactor, prevZoomFactor);
|
||||
prevZoomFactor = cameraControl._zoomFactor;
|
||||
selectionBox.visible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SceneEnvironment {
|
||||
id: sceneEnv
|
||||
antialiasingMode: SceneEnvironment.MSAA
|
||||
antialiasingQuality: SceneEnvironment.High
|
||||
}
|
||||
|
||||
SelectionBox {
|
||||
id: selectionBox
|
||||
view3D: root
|
||||
geometryName: "NodeNodeViewSB"
|
||||
}
|
||||
|
||||
EditCameraController {
|
||||
id: cameraControl
|
||||
camera: theCamera
|
||||
anchors.fill: parent
|
||||
view3d: root
|
||||
ignoreToolState: true
|
||||
}
|
||||
|
||||
DirectionalLight {
|
||||
eulerRotation.x: -30
|
||||
eulerRotation.y: -30
|
||||
}
|
||||
|
||||
PerspectiveCamera {
|
||||
id: theCamera
|
||||
z: 600
|
||||
y: 600
|
||||
x: 600
|
||||
eulerRotation.x: -45
|
||||
eulerRotation.y: -45
|
||||
clipFar: 10000
|
||||
clipNear: 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property Node targetNode
|
||||
property View3D targetView
|
||||
|
||||
property vector3d offset: Qt.vector3d(0, 0, 0)
|
||||
|
||||
property bool isBehindCamera
|
||||
|
||||
onTargetNodeChanged: updateOverlay()
|
||||
|
||||
Connections {
|
||||
target: targetNode
|
||||
function onSceneTransformChanged() { updateOverlay() }
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: targetView.camera
|
||||
function onSceneTransformChanged() { updateOverlay() }
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: _generalHelper
|
||||
function onOverlayUpdateNeeded() { updateOverlay() }
|
||||
}
|
||||
|
||||
function updateOverlay()
|
||||
{
|
||||
var scenePos = targetNode ? targetNode.scenePosition : Qt.vector3d(0, 0, 0);
|
||||
// Need separate variable as scenePos is reference to read-only property
|
||||
var scenePosWithOffset = Qt.vector3d(scenePos.x + offset.x,
|
||||
scenePos.y + offset.y,
|
||||
scenePos.z + offset.z);
|
||||
var viewPos = targetView ? targetView.mapFrom3DScene(scenePosWithOffset)
|
||||
: Qt.vector3d(0, 0, 0);
|
||||
root.x = viewPos.x;
|
||||
root.y = viewPos.y;
|
||||
|
||||
isBehindCamera = viewPos.z <= 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
import MouseArea3D 1.0
|
||||
|
||||
Model {
|
||||
id: rootModel
|
||||
|
||||
property View3D view3D
|
||||
property alias color: gizmoMaterial.diffuseColor
|
||||
property alias priority: mouseArea.priority
|
||||
property Node targetNode: null
|
||||
property bool dragging: mouseArea.dragging
|
||||
property bool active: false
|
||||
property MouseArea3D dragHelper: null
|
||||
property alias mouseArea: mouseArea
|
||||
|
||||
readonly property bool hovering: mouseArea.hovering
|
||||
|
||||
property vector3d _scenePosPressed
|
||||
property vector2d _planePosPressed
|
||||
property vector3d _targetStartPos
|
||||
|
||||
signal pressed(var mouseArea)
|
||||
signal dragged(var mouseArea, vector3d sceneRelativeDistance, vector2d relativeDistance)
|
||||
signal released(var mouseArea, vector3d sceneRelativeDistance, vector2d relativeDistance)
|
||||
|
||||
source: "#Rectangle"
|
||||
|
||||
DefaultMaterial {
|
||||
id: gizmoMaterial
|
||||
diffuseColor: "white"
|
||||
lighting: DefaultMaterial.NoLighting
|
||||
cullMode: Material.NoCulling
|
||||
}
|
||||
materials: gizmoMaterial
|
||||
|
||||
function handlePressed(mouseArea, planePos)
|
||||
{
|
||||
if (!targetNode)
|
||||
return;
|
||||
|
||||
_planePosPressed = planePos;
|
||||
_scenePosPressed = mouseArea.dragHelper.mapPositionToScene(planePos.toVector3d());
|
||||
_targetStartPos = mouseArea.pivotScenePosition(targetNode);
|
||||
pressed(mouseArea);
|
||||
}
|
||||
|
||||
function calcRelativeDistance(mouseArea, planePos)
|
||||
{
|
||||
var scenePointerPos = mouseArea.dragHelper.mapPositionToScene(planePos.toVector3d());
|
||||
return scenePointerPos.minus(_scenePosPressed);
|
||||
}
|
||||
|
||||
function handleDragged(mouseArea, planePos)
|
||||
{
|
||||
if (!targetNode)
|
||||
return;
|
||||
|
||||
dragged(mouseArea, calcRelativeDistance(mouseArea, planePos),
|
||||
planePos.minus(_planePosPressed));
|
||||
}
|
||||
|
||||
function handleReleased(mouseArea, planePos)
|
||||
{
|
||||
if (!targetNode)
|
||||
return;
|
||||
|
||||
released(mouseArea, calcRelativeDistance(mouseArea, planePos),
|
||||
planePos.minus(_planePosPressed));
|
||||
}
|
||||
|
||||
MouseArea3D {
|
||||
id: mouseArea
|
||||
view3D: rootModel.view3D
|
||||
x: -60
|
||||
y: -60
|
||||
width: 120
|
||||
height: 120
|
||||
grabsMouse: targetNode
|
||||
active: rootModel.active
|
||||
dragHelper: rootModel.dragHelper
|
||||
|
||||
onPressed: (planePos)=> {
|
||||
rootModel.handlePressed(mouseArea, planePos);
|
||||
}
|
||||
onDragged: (planePos)=> {
|
||||
rootModel.handleDragged(mouseArea, planePos);
|
||||
}
|
||||
onReleased: (planePos)=> {
|
||||
rootModel.handleReleased(mouseArea, planePos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
import MouseArea3D 1.0
|
||||
|
||||
PlanarDraggable {
|
||||
id: planarHandle
|
||||
scale: Qt.vector3d(0.024, 0.024, 0.024)
|
||||
|
||||
signal positionCommit()
|
||||
signal positionMove()
|
||||
|
||||
function localPos(sceneRelativeDistance)
|
||||
{
|
||||
var newScenePos = Qt.vector3d(
|
||||
_targetStartPos.x + sceneRelativeDistance.x,
|
||||
_targetStartPos.y + sceneRelativeDistance.y,
|
||||
_targetStartPos.z + sceneRelativeDistance.z);
|
||||
return targetNode.parent ? targetNode.parent.mapPositionFromScene(newScenePos) : newScenePos;
|
||||
}
|
||||
|
||||
onPressed: {
|
||||
if (targetNode == multiSelectionNode)
|
||||
_generalHelper.restartMultiSelection();
|
||||
}
|
||||
|
||||
onDragged: (mouseArea, sceneRelativeDistance)=> {
|
||||
targetNode.position = localPos(sceneRelativeDistance);
|
||||
if (targetNode == multiSelectionNode)
|
||||
_generalHelper.moveMultiSelection(false);
|
||||
positionMove();
|
||||
}
|
||||
|
||||
onReleased: (mouseArea, sceneRelativeDistance)=> {
|
||||
targetNode.position = localPos(sceneRelativeDistance);
|
||||
if (targetNode == multiSelectionNode)
|
||||
_generalHelper.moveMultiSelection(true);
|
||||
positionCommit();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
import MouseArea3D 1.0
|
||||
|
||||
PlanarDraggable {
|
||||
id: planarHandle
|
||||
scale: Qt.vector3d(0.024, 0.024, 0.024)
|
||||
|
||||
property bool globalOrientation: false
|
||||
property vector3d axisX
|
||||
property vector3d axisY
|
||||
|
||||
signal scaleCommit()
|
||||
signal scaleChange()
|
||||
|
||||
property vector3d _startScale
|
||||
|
||||
onPressed: {
|
||||
if (targetNode == multiSelectionNode)
|
||||
_generalHelper.restartMultiSelection();
|
||||
_startScale = targetNode.scale;
|
||||
}
|
||||
|
||||
onDragged: (mouseArea, sceneRelativeDistance, relativeDistance)=> {
|
||||
targetNode.scale = mouseArea.getNewScale(_startScale, relativeDistance.times(scale.x),
|
||||
axisX, axisY);
|
||||
if (targetNode == multiSelectionNode)
|
||||
_generalHelper.scaleMultiSelection(false);
|
||||
scaleChange();
|
||||
}
|
||||
|
||||
onReleased: (mouseArea, sceneRelativeDistance, relativeDistance)=> {
|
||||
targetNode.scale = mouseArea.getNewScale(_startScale, relativeDistance.times(scale.x),
|
||||
axisX, axisY);
|
||||
if (targetNode == multiSelectionNode)
|
||||
_generalHelper.scaleMultiSelection(true);
|
||||
scaleCommit();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,293 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
import MouseArea3D 1.0
|
||||
|
||||
Node {
|
||||
id: rotateGizmo
|
||||
|
||||
property View3D view3D
|
||||
property bool highlightOnHover: true
|
||||
property Node targetNode: null
|
||||
property bool globalOrientation: true
|
||||
readonly property bool dragging: cameraRing.dragging
|
||||
|| rotRingX.dragging || rotRingY.dragging || rotRingZ.dragging
|
||||
property MouseArea3D dragHelper: null
|
||||
property real currentAngle
|
||||
property point currentMousePos
|
||||
property alias freeDraggerArea: mouseAreaFree
|
||||
property bool blocked: false
|
||||
|
||||
position: dragHelper.pivotScenePosition(targetNode)
|
||||
|
||||
onTargetNodeChanged: {
|
||||
position = dragHelper.pivotScenePosition(targetNode);
|
||||
blocked = _generalHelper.isRotationBlocked(targetNode);
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: rotateGizmo.targetNode
|
||||
function onSceneTransformChanged()
|
||||
{
|
||||
rotateGizmo.position = dragHelper.pivotScenePosition(targetNode);
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: _generalHelper
|
||||
function onRotationBlocksChanged()
|
||||
{
|
||||
blocked = _generalHelper.isRotationBlocked(targetNode);
|
||||
}
|
||||
}
|
||||
|
||||
signal rotateCommit()
|
||||
signal rotateChange()
|
||||
|
||||
function copyRingProperties(srcRing) {
|
||||
draggingRing.rotation = srcRing.sceneRotation;
|
||||
draggingRing.color = srcRing.color;
|
||||
draggingRing.scale = srcRing.scale;
|
||||
}
|
||||
|
||||
onDraggingChanged: {
|
||||
if (rotRingX.dragging)
|
||||
copyRingProperties(rotRingX)
|
||||
else if (rotRingY.dragging)
|
||||
copyRingProperties(rotRingY)
|
||||
else if (rotRingZ.dragging)
|
||||
copyRingProperties(rotRingZ)
|
||||
}
|
||||
|
||||
Node {
|
||||
id: rotNode
|
||||
rotation: globalOrientation || !rotateGizmo.targetNode ? Qt.quaternion(1, 0, 0, 0)
|
||||
: rotateGizmo.targetNode.sceneRotation
|
||||
visible: !rotateGizmo.dragging && !freeRotator.dragging
|
||||
|
||||
RotateRing {
|
||||
id: rotRingX
|
||||
objectName: "Rotate Ring X"
|
||||
eulerRotation: Qt.vector3d(0, 90, 0)
|
||||
targetNode: rotateGizmo.targetNode
|
||||
color: rotateGizmo.blocked ? Qt.rgba(0.5, 0.5, 0.5, 1)
|
||||
: highlightOnHover && (hovering || dragging)
|
||||
? Qt.lighter(Qt.rgba(1, 0, 0, 1)) : Qt.rgba(1, 0, 0, 1)
|
||||
priority: 40
|
||||
view3D: rotateGizmo.view3D
|
||||
active: rotateGizmo.visible && !rotateGizmo.blocked
|
||||
dragHelper: rotateGizmo.dragHelper
|
||||
|
||||
onRotateCommit: rotateGizmo.rotateCommit()
|
||||
onRotateChange: rotateGizmo.rotateChange()
|
||||
onCurrentAngleChanged: rotateGizmo.currentAngle = currentAngle
|
||||
onCurrentMousePosChanged: rotateGizmo.currentMousePos = currentMousePos
|
||||
}
|
||||
|
||||
RotateRing {
|
||||
id: rotRingY
|
||||
objectName: "Rotate Ring Y"
|
||||
eulerRotation: Qt.vector3d(90, 0, 0)
|
||||
targetNode: rotateGizmo.targetNode
|
||||
color: rotateGizmo.blocked ? Qt.rgba(0.5, 0.5, 0.5, 1)
|
||||
: highlightOnHover && (hovering || dragging)
|
||||
? Qt.lighter(Qt.rgba(0, 0.6, 0, 1)) : Qt.rgba(0, 0.6, 0, 1)
|
||||
// Just a smidge smaller than higher priority rings so that it doesn't obscure them
|
||||
scale: Qt.vector3d(0.998, 0.998, 0.998)
|
||||
priority: 30
|
||||
view3D: rotateGizmo.view3D
|
||||
active: rotateGizmo.visible && !rotateGizmo.blocked
|
||||
dragHelper: rotateGizmo.dragHelper
|
||||
|
||||
onRotateCommit: rotateGizmo.rotateCommit()
|
||||
onRotateChange: rotateGizmo.rotateChange()
|
||||
onCurrentAngleChanged: rotateGizmo.currentAngle = currentAngle
|
||||
onCurrentMousePosChanged: rotateGizmo.currentMousePos = currentMousePos
|
||||
}
|
||||
|
||||
RotateRing {
|
||||
id: rotRingZ
|
||||
objectName: "Rotate Ring Z"
|
||||
eulerRotation: Qt.vector3d(0, 0, 0)
|
||||
targetNode: rotateGizmo.targetNode
|
||||
color: rotateGizmo.blocked ? Qt.rgba(0.5, 0.5, 0.5, 1)
|
||||
: highlightOnHover && (hovering || dragging)
|
||||
? Qt.lighter(Qt.rgba(0, 0, 1, 1)) : Qt.rgba(0, 0, 1, 1)
|
||||
// Just a smidge smaller than higher priority rings so that it doesn't obscure them
|
||||
scale: Qt.vector3d(0.996, 0.996, 0.996)
|
||||
priority: 20
|
||||
view3D: rotateGizmo.view3D
|
||||
active: rotateGizmo.visible && !rotateGizmo.blocked
|
||||
dragHelper: rotateGizmo.dragHelper
|
||||
|
||||
onRotateCommit: rotateGizmo.rotateCommit()
|
||||
onRotateChange: rotateGizmo.rotateChange()
|
||||
onCurrentAngleChanged: rotateGizmo.currentAngle = currentAngle
|
||||
onCurrentMousePosChanged: rotateGizmo.currentMousePos = currentMousePos
|
||||
}
|
||||
}
|
||||
|
||||
RotateRing {
|
||||
// This ring is used as visual proxy during dragging to display the currently dragged
|
||||
// plane in static position, as rotation planes can wobble when ancestors don't have
|
||||
// uniform scaling.
|
||||
// Camera ring doesn't need dragging proxy as it doesn't wobble.
|
||||
id: draggingRing
|
||||
objectName: "draggingRing"
|
||||
targetNode: rotateGizmo.targetNode
|
||||
view3D: rotateGizmo.view3D
|
||||
active: false
|
||||
visible: rotRingX.dragging || rotRingY.dragging || rotRingZ.dragging
|
||||
}
|
||||
|
||||
RotateRing {
|
||||
id: cameraRing
|
||||
objectName: "cameraRing"
|
||||
rotation: rotateGizmo.view3D.camera.rotation
|
||||
targetNode: rotateGizmo.targetNode
|
||||
color: rotateGizmo.blocked ? Qt.rgba(0.5, 0.5, 0.5, 1)
|
||||
: highlightOnHover && (hovering || dragging)
|
||||
? Qt.lighter(Qt.rgba(0.5, 0.5, 0.5, 1))
|
||||
: Qt.rgba(0.5, 0.5, 0.5, 1)
|
||||
scale: Qt.vector3d(1.1, 1.1, 1.1)
|
||||
priority: 10
|
||||
view3D: rotateGizmo.view3D
|
||||
active: rotateGizmo.visible && !rotateGizmo.blocked
|
||||
dragHelper: rotateGizmo.dragHelper
|
||||
visible: !rotRingX.dragging && !rotRingY.dragging && !rotRingZ.dragging && !freeRotator.dragging
|
||||
|
||||
onRotateCommit: rotateGizmo.rotateCommit()
|
||||
onRotateChange: rotateGizmo.rotateChange()
|
||||
onCurrentAngleChanged: rotateGizmo.currentAngle = currentAngle
|
||||
onCurrentMousePosChanged: rotateGizmo.currentMousePos = currentMousePos
|
||||
}
|
||||
|
||||
Model {
|
||||
id: freeRotator
|
||||
|
||||
source: "#Sphere"
|
||||
materials: DefaultMaterial {
|
||||
id: material
|
||||
diffuseColor: "black"
|
||||
opacity: mouseAreaFree.hovering && !rotateGizmo.blocked ? 0.15 : 0
|
||||
lighting: DefaultMaterial.NoLighting
|
||||
}
|
||||
scale: Qt.vector3d(0.15, 0.15, 0.15)
|
||||
visible: !rotateGizmo.dragging && !dragging
|
||||
|
||||
property bool dragging: false
|
||||
property vector3d _pointerPosPressed
|
||||
property vector3d _startRotation
|
||||
|
||||
function handlePressed(screenPos)
|
||||
{
|
||||
if (!rotateGizmo.targetNode)
|
||||
return;
|
||||
|
||||
if (targetNode == multiSelectionNode)
|
||||
_generalHelper.restartMultiSelection();
|
||||
|
||||
// Need to recreate vector as we need to adjust it and we can't do that on reference of
|
||||
// scenePosition, which is read-only property
|
||||
var scenePos = rotateGizmo.dragHelper.pivotScenePosition(rotateGizmo.targetNode);
|
||||
_pointerPosPressed = Qt.vector3d(screenPos.x, screenPos.y, 0);
|
||||
|
||||
// Recreate vector so we don't follow the changes in targetNode.rotation
|
||||
_startRotation = Qt.vector3d(rotateGizmo.targetNode.eulerRotation.x,
|
||||
rotateGizmo.targetNode.eulerRotation.y,
|
||||
rotateGizmo.targetNode.eulerRotation.z);
|
||||
// Ensure we never set NaN values for rotation, even if target node originally has them
|
||||
if (isNaN(_startRotation.x))
|
||||
_startRotation.x = 0;
|
||||
if (isNaN(_startRotation.y))
|
||||
_startRotation.y = 0;
|
||||
if (isNaN(_startRotation.z))
|
||||
_startRotation.z = 0;
|
||||
|
||||
dragging = true;
|
||||
}
|
||||
|
||||
function handleDragged(screenPos)
|
||||
{
|
||||
if (!rotateGizmo.targetNode)
|
||||
return;
|
||||
|
||||
mouseAreaFree.applyFreeRotation(
|
||||
rotateGizmo.targetNode, _startRotation, _pointerPosPressed,
|
||||
Qt.vector3d(screenPos.x, screenPos.y, 0));
|
||||
|
||||
if (targetNode == multiSelectionNode)
|
||||
_generalHelper.rotateMultiSelection(false);
|
||||
|
||||
rotateGizmo.rotateChange();
|
||||
}
|
||||
|
||||
function handleReleased(screenPos)
|
||||
{
|
||||
if (!rotateGizmo.targetNode)
|
||||
return;
|
||||
|
||||
mouseAreaFree.applyFreeRotation(
|
||||
rotateGizmo.targetNode, _startRotation, _pointerPosPressed,
|
||||
Qt.vector3d(screenPos.x, screenPos.y, 0));
|
||||
|
||||
if (targetNode == multiSelectionNode)
|
||||
_generalHelper.rotateMultiSelection(true);
|
||||
|
||||
rotateGizmo.rotateCommit();
|
||||
dragging = false;
|
||||
|
||||
if (targetNode == multiSelectionNode)
|
||||
_generalHelper.resetMultiSelectionNode();
|
||||
}
|
||||
|
||||
MouseArea3D {
|
||||
id: mouseAreaFree
|
||||
view3D: rotateGizmo.view3D
|
||||
rotation: rotateGizmo.view3D.camera.rotation
|
||||
objectName: "Free rotator plane"
|
||||
x: -50
|
||||
y: -50
|
||||
width: 100
|
||||
height: 100
|
||||
circlePickArea: Qt.point(25, 50)
|
||||
grabsMouse: rotateGizmo.targetNode
|
||||
active: rotateGizmo.visible && !rotateGizmo.blocked
|
||||
dragHelper: rotateGizmo.dragHelper
|
||||
|
||||
onPressed: (planePos, screenPos)=> {
|
||||
freeRotator.handlePressed(screenPos);
|
||||
}
|
||||
onDragged: (planePos, screenPos)=> {
|
||||
freeRotator.handleDragged(screenPos);
|
||||
}
|
||||
onReleased: (planePos, screenPos)=> {
|
||||
freeRotator.handleReleased(screenPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
import MouseArea3D 1.0
|
||||
|
||||
Model {
|
||||
id: rotateRing
|
||||
|
||||
property View3D view3D
|
||||
property alias color: material.diffuseColor
|
||||
property Node targetNode: null
|
||||
property bool dragging: mouseAreaMain.dragging
|
||||
property bool active: false
|
||||
property alias hovering: mouseAreaMain.hovering
|
||||
property alias priority: mouseAreaMain.priority
|
||||
property real currentAngle
|
||||
property point currentMousePos
|
||||
property MouseArea3D dragHelper: null
|
||||
|
||||
property vector3d _pointerPosPressed
|
||||
property vector3d _targetPosOnScreen
|
||||
property vector3d _startRotation
|
||||
property bool _trackBall
|
||||
|
||||
signal rotateCommit()
|
||||
signal rotateChange()
|
||||
|
||||
source: "../meshes/ring.mesh"
|
||||
|
||||
Model {
|
||||
id: pickModel
|
||||
objectName: "PickModel for " + rotateRing.objectName
|
||||
source: "../meshes/ringselect.mesh"
|
||||
pickable: true
|
||||
}
|
||||
|
||||
materials: DefaultMaterial {
|
||||
id: material
|
||||
diffuseColor: "white"
|
||||
lighting: DefaultMaterial.NoLighting
|
||||
}
|
||||
|
||||
function applyLocalRotation(screenPos)
|
||||
{
|
||||
currentAngle = mouseAreaMain.dragHelper.getNewRotationAngle(
|
||||
targetNode, _pointerPosPressed, Qt.vector3d(screenPos.x, screenPos.y, 0),
|
||||
_targetPosOnScreen, currentAngle, _trackBall);
|
||||
mouseAreaMain.dragHelper.applyRotationAngleToNode(targetNode, _startRotation, currentAngle);
|
||||
}
|
||||
|
||||
function handlePressed(screenPos, angle)
|
||||
{
|
||||
if (!targetNode)
|
||||
return;
|
||||
|
||||
if (targetNode == multiSelectionNode)
|
||||
_generalHelper.restartMultiSelection();
|
||||
|
||||
// Need to recreate vector as we need to adjust it and we can't do that on reference of
|
||||
// scenePosition, which is read-only property
|
||||
var scenePos = mouseAreaMain.pivotScenePosition(targetNode);
|
||||
|
||||
_targetPosOnScreen = view3D.mapFrom3DScene(scenePos);
|
||||
_targetPosOnScreen.z = 0;
|
||||
_pointerPosPressed = Qt.vector3d(screenPos.x, screenPos.y, 0);
|
||||
_trackBall = angle < 0.1;
|
||||
|
||||
// Recreate vector so we don't follow the changes in targetNode.eulerRotation
|
||||
_startRotation = Qt.vector3d(targetNode.eulerRotation.x,
|
||||
targetNode.eulerRotation.y,
|
||||
targetNode.eulerRotation.z);
|
||||
// Ensure we never set NaN values for rotation, even if target node originally has them
|
||||
if (isNaN(_startRotation.x))
|
||||
_startRotation.x = 0;
|
||||
if (isNaN(_startRotation.y))
|
||||
_startRotation.y = 0;
|
||||
if (isNaN(_startRotation.z))
|
||||
_startRotation.z = 0;
|
||||
currentAngle = 0;
|
||||
currentMousePos = screenPos;
|
||||
}
|
||||
|
||||
function handleDragged(screenPos)
|
||||
{
|
||||
if (!targetNode)
|
||||
return;
|
||||
|
||||
applyLocalRotation(screenPos);
|
||||
|
||||
if (targetNode == multiSelectionNode)
|
||||
_generalHelper.rotateMultiSelection(false);
|
||||
|
||||
currentMousePos = screenPos;
|
||||
rotateChange();
|
||||
}
|
||||
|
||||
function handleReleased(screenPos)
|
||||
{
|
||||
if (!targetNode)
|
||||
return;
|
||||
|
||||
applyLocalRotation(screenPos);
|
||||
|
||||
if (targetNode == multiSelectionNode)
|
||||
_generalHelper.rotateMultiSelection(true);
|
||||
|
||||
rotateCommit();
|
||||
currentAngle = 0;
|
||||
currentMousePos = screenPos;
|
||||
|
||||
if (targetNode == multiSelectionNode)
|
||||
_generalHelper.resetMultiSelectionNode();
|
||||
}
|
||||
|
||||
MouseArea3D {
|
||||
id: mouseAreaMain
|
||||
view3D: rotateRing.view3D
|
||||
objectName: "Main plane of " + rotateRing.objectName
|
||||
x: -30
|
||||
y: -30
|
||||
width: 60
|
||||
height: 60
|
||||
circlePickArea: Qt.point(9.2, 1.4)
|
||||
grabsMouse: targetNode
|
||||
active: rotateRing.active
|
||||
pickNode: pickModel
|
||||
minAngle: 0.05
|
||||
dragHelper: rotateRing.dragHelper
|
||||
|
||||
onPressed: (planePos, screenPos, angle)=> {
|
||||
rotateRing.handlePressed(screenPos, angle);
|
||||
}
|
||||
onDragged: (planePos, screenPos)=> {
|
||||
rotateRing.handleDragged(screenPos);
|
||||
}
|
||||
onReleased: (planePos, screenPos)=> {
|
||||
rotateRing.handleReleased(screenPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
import MouseArea3D 1.0
|
||||
|
||||
Node {
|
||||
id: scaleGizmo
|
||||
|
||||
property View3D view3D
|
||||
property bool highlightOnHover: false
|
||||
property Node targetNode: null
|
||||
readonly property bool dragging: scaleRodX.dragging || scaleRodY.dragging || scaleRodZ.dragging
|
||||
|| planeX.dragging || planeY.dragging || planeZ.dragging
|
||||
|| centerMouseArea.dragging
|
||||
property MouseArea3D dragHelper: null
|
||||
property alias freeDraggerArea: centerMouseArea
|
||||
|
||||
position: dragHelper.pivotScenePosition(targetNode)
|
||||
|
||||
onTargetNodeChanged: position = dragHelper.pivotScenePosition(targetNode)
|
||||
|
||||
Connections {
|
||||
target: scaleGizmo.targetNode
|
||||
function onSceneTransformChanged()
|
||||
{
|
||||
scaleGizmo.position = scaleGizmo.dragHelper.pivotScenePosition(scaleGizmo.targetNode);
|
||||
}
|
||||
}
|
||||
|
||||
signal scaleCommit()
|
||||
signal scaleChange()
|
||||
|
||||
Node {
|
||||
rotation: !targetNode ? Qt.quaternion(1, 0, 0, 0) : targetNode.sceneRotation
|
||||
|
||||
ScaleRod {
|
||||
id: scaleRodX
|
||||
eulerRotation: Qt.vector3d(0, 0, -90)
|
||||
axis: Qt.vector3d(1, 0, 0)
|
||||
targetNode: scaleGizmo.targetNode
|
||||
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(1, 0, 0, 1))
|
||||
: Qt.rgba(1, 0, 0, 1)
|
||||
view3D: scaleGizmo.view3D
|
||||
active: scaleGizmo.visible
|
||||
dragHelper: scaleGizmo.dragHelper
|
||||
|
||||
onScaleCommit: scaleGizmo.scaleCommit()
|
||||
onScaleChange: scaleGizmo.scaleChange()
|
||||
}
|
||||
|
||||
ScaleRod {
|
||||
id: scaleRodY
|
||||
eulerRotation: Qt.vector3d(0, 0, 0)
|
||||
axis: Qt.vector3d(0, 1, 0)
|
||||
targetNode: scaleGizmo.targetNode
|
||||
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0, 0.6, 0, 1))
|
||||
: Qt.rgba(0, 0.6, 0, 1)
|
||||
view3D: scaleGizmo.view3D
|
||||
active: scaleGizmo.visible
|
||||
dragHelper: scaleGizmo.dragHelper
|
||||
|
||||
onScaleCommit: scaleGizmo.scaleCommit()
|
||||
onScaleChange: scaleGizmo.scaleChange()
|
||||
}
|
||||
|
||||
ScaleRod {
|
||||
id: scaleRodZ
|
||||
eulerRotation: Qt.vector3d(90, 0, 0)
|
||||
axis: Qt.vector3d(0, 0, 1)
|
||||
targetNode: scaleGizmo.targetNode
|
||||
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0, 0, 1, 1))
|
||||
: Qt.rgba(0, 0, 1, 1)
|
||||
view3D: scaleGizmo.view3D
|
||||
active: scaleGizmo.visible
|
||||
dragHelper: scaleGizmo.dragHelper
|
||||
|
||||
onScaleCommit: scaleGizmo.scaleCommit()
|
||||
onScaleChange: scaleGizmo.scaleChange()
|
||||
}
|
||||
|
||||
PlanarScaleHandle {
|
||||
id: planeX
|
||||
|
||||
y: 10
|
||||
z: 10
|
||||
|
||||
eulerRotation: Qt.vector3d(0, 90, 0)
|
||||
axisX: Qt.vector3d(0, 0, -1)
|
||||
axisY: Qt.vector3d(0, 1, 0)
|
||||
targetNode: scaleGizmo.targetNode
|
||||
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(1, 0, 0, 1))
|
||||
: Qt.rgba(1, 0, 0, 1)
|
||||
view3D: scaleGizmo.view3D
|
||||
active: scaleGizmo.visible
|
||||
dragHelper: scaleGizmo.dragHelper
|
||||
|
||||
onScaleCommit: scaleGizmo.scaleCommit()
|
||||
onScaleChange: scaleGizmo.scaleChange()
|
||||
}
|
||||
|
||||
PlanarScaleHandle {
|
||||
id: planeY
|
||||
|
||||
x: 10
|
||||
z: 10
|
||||
|
||||
eulerRotation: Qt.vector3d(90, 0, 0)
|
||||
axisX: Qt.vector3d(1, 0, 0)
|
||||
axisY: Qt.vector3d(0, 0, 1)
|
||||
targetNode: scaleGizmo.targetNode
|
||||
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0, 0.6, 0, 1))
|
||||
: Qt.rgba(0, 0.6, 0, 1)
|
||||
view3D: scaleGizmo.view3D
|
||||
active: scaleGizmo.visible
|
||||
dragHelper: scaleGizmo.dragHelper
|
||||
|
||||
onScaleCommit: scaleGizmo.scaleCommit()
|
||||
onScaleChange: scaleGizmo.scaleChange()
|
||||
}
|
||||
|
||||
PlanarScaleHandle {
|
||||
id: planeZ
|
||||
|
||||
x: 10
|
||||
y: 10
|
||||
|
||||
eulerRotation: Qt.vector3d(0, 0, 0)
|
||||
axisX: Qt.vector3d(1, 0, 0)
|
||||
axisY: Qt.vector3d(0, 1, 0)
|
||||
targetNode: scaleGizmo.targetNode
|
||||
color: highlightOnHover && (hovering || dragging) ? Qt.lighter(Qt.rgba(0, 0, 1, 1))
|
||||
: Qt.rgba(0, 0, 1, 1)
|
||||
view3D: scaleGizmo.view3D
|
||||
active: scaleGizmo.visible
|
||||
dragHelper: scaleGizmo.dragHelper
|
||||
|
||||
onScaleCommit: scaleGizmo.scaleCommit()
|
||||
onScaleChange: scaleGizmo.scaleChange()
|
||||
}
|
||||
}
|
||||
|
||||
Model {
|
||||
id: centerCube
|
||||
|
||||
source: "#Cube"
|
||||
scale: Qt.vector3d(0.024, 0.024, 0.024)
|
||||
materials: DefaultMaterial {
|
||||
id: material
|
||||
diffuseColor: highlightOnHover
|
||||
&& (centerMouseArea.hovering || centerMouseArea.dragging)
|
||||
? Qt.lighter(Qt.rgba(0.5, 0.5, 0.5, 1))
|
||||
: Qt.rgba(0.5, 0.5, 0.5, 1)
|
||||
lighting: DefaultMaterial.NoLighting
|
||||
}
|
||||
|
||||
MouseArea3D {
|
||||
id: centerMouseArea
|
||||
view3D: scaleGizmo.view3D
|
||||
x: -60
|
||||
y: -60
|
||||
width: 120
|
||||
height: 120
|
||||
rotation: view3D.camera.rotation
|
||||
grabsMouse: scaleGizmo.targetNode
|
||||
priority: 10
|
||||
active: scaleGizmo.visible
|
||||
dragHelper: scaleGizmo.dragHelper
|
||||
|
||||
property vector3d _startScale
|
||||
property point _startScreenPos
|
||||
|
||||
function localScale(screenPos)
|
||||
{
|
||||
var yDelta = screenPos.y - _startScreenPos.y;
|
||||
if (yDelta === 0)
|
||||
return _startScale;
|
||||
var scaler = 1.0 + (yDelta * 0.025);
|
||||
if (scaler === 0)
|
||||
scaler = 0.0001;
|
||||
return Qt.vector3d(scaler * _startScale.x,
|
||||
scaler * _startScale.y,
|
||||
scaler * _startScale.z);
|
||||
}
|
||||
|
||||
onPressed: (planePos, screenPos)=> {
|
||||
if (!scaleGizmo.targetNode)
|
||||
return;
|
||||
|
||||
if (targetNode == multiSelectionNode)
|
||||
_generalHelper.restartMultiSelection();
|
||||
|
||||
// Recreate vector so we don't follow the changes in targetNode.scale
|
||||
_startScale = Qt.vector3d(scaleGizmo.targetNode.scale.x,
|
||||
scaleGizmo.targetNode.scale.y,
|
||||
scaleGizmo.targetNode.scale.z);
|
||||
_startScreenPos = screenPos;
|
||||
}
|
||||
onDragged: (planePos, screenPos)=> {
|
||||
if (!scaleGizmo.targetNode)
|
||||
return;
|
||||
scaleGizmo.targetNode.scale = localScale(screenPos);
|
||||
if (targetNode == multiSelectionNode)
|
||||
_generalHelper.scaleMultiSelection(false);
|
||||
scaleGizmo.scaleChange();
|
||||
}
|
||||
onReleased: (planePos, screenPos)=> {
|
||||
if (!scaleGizmo.targetNode)
|
||||
return;
|
||||
|
||||
scaleGizmo.targetNode.scale = localScale(screenPos);
|
||||
if (targetNode == multiSelectionNode)
|
||||
_generalHelper.scaleMultiSelection(true);
|
||||
scaleGizmo.scaleCommit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
import MouseArea3D 1.0
|
||||
|
||||
DirectionalDraggable {
|
||||
id: scaleRod
|
||||
source: "../meshes/scalerod.mesh"
|
||||
|
||||
property vector3d axis
|
||||
|
||||
signal scaleCommit()
|
||||
signal scaleChange()
|
||||
|
||||
property vector3d _startScale
|
||||
|
||||
Model {
|
||||
source: "#Cube"
|
||||
y: 10
|
||||
scale: Qt.vector3d(0.020, 0.020, 0.020)
|
||||
materials: DefaultMaterial {
|
||||
id: material
|
||||
diffuseColor: scaleRod.color
|
||||
lighting: DefaultMaterial.NoLighting
|
||||
}
|
||||
}
|
||||
|
||||
onPressed: {
|
||||
if (targetNode == multiSelectionNode)
|
||||
_generalHelper.restartMultiSelection();
|
||||
_startScale = targetNode.scale;
|
||||
}
|
||||
|
||||
onDragged: (mouseArea, sceneRelativeDistance, relativeDistance)=> {
|
||||
targetNode.scale = mouseArea.getNewScale(_startScale, Qt.vector2d(relativeDistance, 0),
|
||||
axis, Qt.vector3d(0, 0, 0));
|
||||
if (targetNode == multiSelectionNode)
|
||||
_generalHelper.scaleMultiSelection(false);
|
||||
scaleChange();
|
||||
}
|
||||
|
||||
onReleased: (mouseArea, sceneRelativeDistance, relativeDistance)=> {
|
||||
targetNode.scale = mouseArea.getNewScale(_startScale, Qt.vector2d(relativeDistance, 0),
|
||||
axis, Qt.vector3d(0, 0, 0));
|
||||
if (targetNode == multiSelectionNode)
|
||||
_generalHelper.scaleMultiSelection(true);
|
||||
scaleCommit();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 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 QtQuick3D 6.0
|
||||
|
||||
View3D {
|
||||
id: sceneView
|
||||
anchors.fill: parent
|
||||
|
||||
property bool usePerspective: false
|
||||
property alias showSceneLight: sceneLight.visible
|
||||
property alias showGrid: helperGrid.visible
|
||||
property alias sceneHelpers: sceneHelpers
|
||||
property alias perspectiveCamera: scenePerspectiveCamera
|
||||
property alias orthoCamera: sceneOrthoCamera
|
||||
property double cameraZoomFactor: .55;
|
||||
|
||||
// Empirical cameraZoomFactor values at which the grid zoom level is doubled. The values are
|
||||
// approximately uniformally distributed over the non-linear range of cameraZoomFactor.
|
||||
readonly property var grid_thresholds: [0.55, 1.10, 2.35, 4.9, 10.0, 20.5, 42.0, 85.0, 999999.0]
|
||||
property var thresIdx: 1
|
||||
property var thresPerc: 1.0 // percentage of cameraZoomFactor to the current grid zoom threshold (0.0 - 1.0)
|
||||
|
||||
camera: usePerspective ? scenePerspectiveCamera : sceneOrthoCamera
|
||||
|
||||
onCameraZoomFactorChanged: {
|
||||
thresIdx = Math.max(1, grid_thresholds.findIndex(v => v > cameraZoomFactor));
|
||||
thresPerc = (grid_thresholds[thresIdx] - cameraZoomFactor) / (grid_thresholds[thresIdx] - grid_thresholds[thresIdx - 1]);
|
||||
}
|
||||
|
||||
Node {
|
||||
id: sceneHelpers
|
||||
|
||||
HelperGrid {
|
||||
id: helperGrid
|
||||
lines: Math.pow(2, grid_thresholds.length - thresIdx - 1);
|
||||
step: 100 * grid_thresholds[0] * Math.pow(2, thresIdx - 1);
|
||||
subdivAlpha: thresPerc;
|
||||
}
|
||||
|
||||
PointLight {
|
||||
id: sceneLight
|
||||
position: usePerspective ? scenePerspectiveCamera.position
|
||||
: sceneOrthoCamera.position
|
||||
quadraticFade: 0
|
||||
linearFade: 0
|
||||
}
|
||||
|
||||
// Initial camera position and rotation should be such that they look at origin.
|
||||
// Otherwise EditCameraController._lookAtPoint needs to be initialized to correct
|
||||
// point.
|
||||
PerspectiveCamera {
|
||||
id: scenePerspectiveCamera
|
||||
z: 600
|
||||
y: 600
|
||||
eulerRotation.x: -45
|
||||
clipFar: 100000
|
||||
clipNear: 1
|
||||
}
|
||||
|
||||
OrthographicCamera {
|
||||
id: sceneOrthoCamera
|
||||
z: 600
|
||||
y: 600
|
||||
eulerRotation.x: -45
|
||||
clipFar: 100000
|
||||
clipNear: -10000
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
import SelectionBoxGeometry 1.0
|
||||
|
||||
Node {
|
||||
id: selectionBox
|
||||
|
||||
property View3D view3D
|
||||
property Node targetNode: null
|
||||
property alias model: selectionBoxModel
|
||||
property alias geometryName: selectionBoxGeometry.name
|
||||
|
||||
SelectionBoxGeometry {
|
||||
id: selectionBoxGeometry
|
||||
name: "Selection Box of 3D Edit View"
|
||||
view3D: selectionBox.view3D
|
||||
targetNode: selectionBox.targetNode
|
||||
rootNode: selectionBox
|
||||
}
|
||||
|
||||
Model {
|
||||
id: selectionBoxModel
|
||||
geometry: selectionBoxGeometry
|
||||
|
||||
scale: selectionBox.targetNode ? selectionBox.targetNode.scale : Qt.vector3d(1, 1, 1)
|
||||
rotation: selectionBox.targetNode ? selectionBox.targetNode.rotation : Qt.quaternion(1, 0, 0, 0)
|
||||
position: selectionBox.targetNode ? selectionBox.targetNode.position : Qt.vector3d(0, 0, 0)
|
||||
pivot: selectionBox.targetNode ? selectionBox.targetNode.pivot : Qt.vector3d(0, 0, 0)
|
||||
|
||||
visible: selectionBox.targetNode && !selectionBoxGeometry.isEmpty
|
||||
|
||||
materials: [
|
||||
DefaultMaterial {
|
||||
diffuseColor: "#fff600"
|
||||
lighting: DefaultMaterial.NoLighting
|
||||
cullMode: Material.NoCulling
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 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 6.0
|
||||
import QtQuick3D 6.0
|
||||
|
||||
DirectionalDraggable {
|
||||
id: handleRoot
|
||||
|
||||
property string currentLabel
|
||||
property point currentMousePos
|
||||
property string propName
|
||||
property real propValue: 0
|
||||
property real newValue: 0
|
||||
|
||||
scale: autoScaler.getScale(Qt.vector3d(5, 5, 5))
|
||||
length: 3
|
||||
offset: -1.5
|
||||
|
||||
Model {
|
||||
id: handle
|
||||
source: "#Sphere"
|
||||
materials: [ handleRoot.material ]
|
||||
scale: Qt.vector3d(0.02, 0.02, 0.02)
|
||||
}
|
||||
|
||||
AutoScaleHelper {
|
||||
id: autoScaler
|
||||
active: handleRoot.active
|
||||
view3D: handleRoot.view3D
|
||||
}
|
||||
|
||||
property real _startAngle
|
||||
|
||||
signal valueCommit()
|
||||
signal valueChange()
|
||||
|
||||
function updateAngle(relativeDistance, screenPos)
|
||||
{
|
||||
handleRoot.newValue = Math.round(Math.min(180, Math.max(0, _startAngle + relativeDistance)));
|
||||
var l = Qt.locale();
|
||||
handleRoot.currentLabel = propName + qsTr(": ") + Number(newValue).toLocaleString(l, 'f', 0);
|
||||
handleRoot.currentMousePos = screenPos;
|
||||
}
|
||||
|
||||
onPressed: (mouseArea, screenPos)=> {
|
||||
_startAngle = propValue;
|
||||
updateAngle(0, screenPos);
|
||||
}
|
||||
|
||||
onDragged: (mouseArea, sceneRelativeDistance, relativeDistance, screenPos)=> {
|
||||
updateAngle(relativeDistance, screenPos);
|
||||
handleRoot.valueChange();
|
||||
}
|
||||
|
||||
onReleased: (mouseArea, sceneRelativeDistance, relativeDistance, screenPos)=> {
|
||||
updateAngle(relativeDistance, screenPos);
|
||||
handleRoot.valueCommit();
|
||||
}
|
||||
}
|
||||
@@ -96,11 +96,13 @@ void IconRenderer::setupRender()
|
||||
if (auto scene = qobject_cast<QQuick3DNode *>(iconItem)) {
|
||||
qmlRegisterType<QmlDesigner::Internal::SelectionBoxGeometry>("SelectionBoxGeometry", 1, 0, "SelectionBoxGeometry");
|
||||
QQmlComponent component(engine);
|
||||
component.loadUrl(QUrl("qrc:/qtquickplugin/mockfiles/IconRenderer3D.qml"));
|
||||
m_containerItem = qobject_cast<QQuickItem *>(component.create());
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
component.loadUrl(QUrl("qrc:/qtquickplugin/mockfiles/qt5/IconRenderer3D.qml"));
|
||||
m_containerItem = qobject_cast<QQuickItem *>(component.create());
|
||||
DesignerSupport::setRootItem(view, m_containerItem);
|
||||
#else
|
||||
component.loadUrl(QUrl("qrc:/qtquickplugin/mockfiles/qt6/IconRenderer3D.qml"));
|
||||
m_containerItem = qobject_cast<QQuickItem *>(component.create());
|
||||
m_window->contentItem()->setSize(m_containerItem->size());
|
||||
m_window->setGeometry(0, 0, m_containerItem->width(), m_containerItem->height());
|
||||
m_containerItem->setParentItem(m_window->contentItem());
|
||||
|
||||
+17
-4
@@ -392,8 +392,11 @@ void Qt5InformationNodeInstanceServer::createEditView3D()
|
||||
new QmlDesigner::Internal::IconGizmoImageProvider);
|
||||
m_3dHelper = helper;
|
||||
|
||||
createAuxiliaryQuickView(QUrl("qrc:/qtquickplugin/mockfiles/EditView3D.qml"), m_editView3DData);
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
createAuxiliaryQuickView(QUrl("qrc:/qtquickplugin/mockfiles/qt6/EditView3D.qml"), m_editView3DData);
|
||||
#else
|
||||
createAuxiliaryQuickView(QUrl("qrc:/qtquickplugin/mockfiles/qt5/EditView3D.qml"), m_editView3DData);
|
||||
#endif
|
||||
if (m_editView3DData.rootItem)
|
||||
helper->setParent(m_editView3DData.rootItem);
|
||||
#endif
|
||||
@@ -1192,12 +1195,22 @@ void Qt5InformationNodeInstanceServer::initializeAuxiliaryViews()
|
||||
#ifdef QUICK3D_MODULE
|
||||
if (isQuick3DMode())
|
||||
createEditView3D();
|
||||
createAuxiliaryQuickView(QUrl("qrc:/qtquickplugin/mockfiles/ModelNode3DImageView.qml"),
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
createAuxiliaryQuickView(QUrl("qrc:/qtquickplugin/mockfiles/qt6/ModelNode3DImageView.qml"),
|
||||
m_modelNode3DImageViewData);
|
||||
#else
|
||||
createAuxiliaryQuickView(QUrl("qrc:/qtquickplugin/mockfiles/qt5/ModelNode3DImageView.qml"),
|
||||
m_modelNode3DImageViewData);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
createAuxiliaryQuickView(QUrl("qrc:/qtquickplugin/mockfiles/ModelNode2DImageView.qml"),
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
createAuxiliaryQuickView(QUrl("qrc:/qtquickplugin/mockfiles/qt6/ModelNode2DImageView.qml"),
|
||||
m_modelNode2DImageViewData);
|
||||
#else
|
||||
createAuxiliaryQuickView(QUrl("qrc:/qtquickplugin/mockfiles/qt5/ModelNode2DImageView.qml"),
|
||||
m_modelNode2DImageViewData);
|
||||
#endif
|
||||
m_modelNode2DImageViewData.window->setDefaultAlphaBuffer(true);
|
||||
m_modelNode2DImageViewData.window->setColor(Qt::transparent);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,9 @@ include (import3d/import3d.pri)
|
||||
SOURCES += $$PWD/qml2puppetmain.cpp
|
||||
RESOURCES += $$PWD/../qmlpuppet.qrc
|
||||
|
||||
versionAtLeast(QT_VERSION, 6.0.0): RESOURCES += $$PWD/../editor3d_qt6.qrc
|
||||
else: RESOURCES += $$PWD/../editor3d_qt5.qrc
|
||||
|
||||
DISTFILES += Info.plist
|
||||
|
||||
unix:!openbsd:!osx: LIBS += -lrt # posix shared memory
|
||||
|
||||
@@ -9,58 +9,7 @@
|
||||
<file>mockfiles/SwipeView.qml</file>
|
||||
<file>mockfiles/GenericBackend.qml</file>
|
||||
<file>mockfiles/Dialog.qml</file>
|
||||
<file>mockfiles/IconRenderer3D.qml</file>
|
||||
<file>mockfiles/EditView3D.qml</file>
|
||||
<file>mockfiles/EditCameraController.qml</file>
|
||||
<file>mockfiles/Arrow.qml</file>
|
||||
<file>mockfiles/AutoScaleHelper.qml</file>
|
||||
<file>mockfiles/MoveGizmo.qml</file>
|
||||
<file>mockfiles/CameraFrustum.qml</file>
|
||||
<file>mockfiles/CameraGizmo.qml</file>
|
||||
<file>mockfiles/LightModel.qml</file>
|
||||
<file>mockfiles/LightIconGizmo.qml</file>
|
||||
<file>mockfiles/LightGizmo.qml</file>
|
||||
<file>mockfiles/AdjustableArrow.qml</file>
|
||||
<file>mockfiles/FadeHandle.qml</file>
|
||||
<file>mockfiles/AreaLightHandle.qml</file>
|
||||
<file>mockfiles/SpotLightHandle.qml</file>
|
||||
<file>mockfiles/IconGizmo.qml</file>
|
||||
<file>mockfiles/Overlay2D.qml</file>
|
||||
<file>mockfiles/HelperGrid.qml</file>
|
||||
<file>mockfiles/DirectionalDraggable.qml</file>
|
||||
<file>mockfiles/PlanarDraggable.qml</file>
|
||||
<file>mockfiles/PlanarMoveHandle.qml</file>
|
||||
<file>mockfiles/PlanarScaleHandle.qml</file>
|
||||
<file>mockfiles/ScaleRod.qml</file>
|
||||
<file>mockfiles/ScaleGizmo.qml</file>
|
||||
<file>mockfiles/ToolBarButton.qml</file>
|
||||
<file>mockfiles/ToggleButton.qml</file>
|
||||
<file>mockfiles/RotateGizmo.qml</file>
|
||||
<file>mockfiles/RotateRing.qml</file>
|
||||
<file>mockfiles/SceneView3D.qml</file>
|
||||
<file>mockfiles/SelectionBox.qml</file>
|
||||
<file>mockfiles/AxisHelper.qml</file>
|
||||
<file>mockfiles/AxisHelperArm.qml</file>
|
||||
<file>mockfiles/Line3D.qml</file>
|
||||
<file>mockfiles/ModelNode3DImageView.qml</file>
|
||||
<file>mockfiles/ModelNode2DImageView.qml</file>
|
||||
<file>mockfiles/MaterialNodeView.qml</file>
|
||||
<file>mockfiles/ModelNodeView.qml</file>
|
||||
<file>mockfiles/NodeNodeView.qml</file>
|
||||
<file>mockfiles/meshes/arrow.mesh</file>
|
||||
<file>mockfiles/meshes/scalerod.mesh</file>
|
||||
<file>mockfiles/meshes/ring.mesh</file>
|
||||
<file>mockfiles/meshes/ringselect.mesh</file>
|
||||
<file>mockfiles/meshes/axishelper.mesh</file>
|
||||
<file>mockfiles/images/editor_camera.png</file>
|
||||
<file>mockfiles/images/editor_camera@2x.png</file>
|
||||
<file>mockfiles/images/area.png</file>
|
||||
<file>mockfiles/images/area@2x.png</file>
|
||||
<file>mockfiles/images/directional.png</file>
|
||||
<file>mockfiles/images/directional@2x.png</file>
|
||||
<file>mockfiles/images/point.png</file>
|
||||
<file>mockfiles/images/point@2x.png</file>
|
||||
<file>mockfiles/images/spot.png</file>
|
||||
<file>mockfiles/images/spot@2x.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -107,6 +107,20 @@ add_qtc_executable(qml2puppet
|
||||
DESTINATION ${DESTDIR}
|
||||
)
|
||||
|
||||
extend_qtc_executable(qml2puppet
|
||||
CONDITION Qt5_VERSION VERSION_GREATER_EQUAL 6.0.0
|
||||
SOURCES_PREFIX "${SRCDIR}/"
|
||||
SOURCES
|
||||
"editor3d_qt6.qrc"
|
||||
)
|
||||
|
||||
extend_qtc_executable(qml2puppet
|
||||
CONDITION Qt5_VERSION VERSION_LESS 6.0.0
|
||||
SOURCES_PREFIX "${SRCDIR}/"
|
||||
SOURCES
|
||||
"editor3d_qt5.qrc"
|
||||
)
|
||||
|
||||
extend_qtc_executable(qml2puppet
|
||||
CONDITION UNIX AND (NOT APPLE)
|
||||
DEPENDS rt
|
||||
|
||||
@@ -166,6 +166,20 @@ QtcTool {
|
||||
files: ["sharedmemory_qt.cpp"]
|
||||
}
|
||||
|
||||
Group {
|
||||
name: "puppet2 3D editor Qt5"
|
||||
condition: !product.usesQt6
|
||||
prefix: puppetDir + "/"
|
||||
files: ["editor3d_qt5.qrc"]
|
||||
}
|
||||
|
||||
Group {
|
||||
name: "puppet2 3D editor Qt6"
|
||||
condition: product.usesQt6
|
||||
prefix: puppetDir + "/"
|
||||
files: ["editor3d_qt6.qrc"]
|
||||
}
|
||||
|
||||
Group {
|
||||
name: "puppet2 sources"
|
||||
prefix: puppetDir + "/qml2puppet/"
|
||||
|
||||
Reference in New Issue
Block a user