forked from qt-creator/qt-creator
QmlDesigner: Implement selection box to 3D edit view
Change-Id: Ib0b13ecd7946e3b7da8ed06d4f5965e06e51a152 Fixes: QDS-1210 Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -200,6 +200,11 @@ Window {
|
||||
step: 50
|
||||
}
|
||||
|
||||
SelectionBox {
|
||||
view3D: editView
|
||||
targetNode: viewWindow.selectedNode
|
||||
}
|
||||
|
||||
PointLight {
|
||||
id: editLight
|
||||
visible: showEditLight
|
||||
|
@@ -84,7 +84,7 @@ Node {
|
||||
anchors.fill: parent
|
||||
cached: true
|
||||
source: iconImage
|
||||
color: transparent
|
||||
color: "transparent"
|
||||
opacity: 0.6
|
||||
}
|
||||
|
||||
|
@@ -29,11 +29,13 @@ import QtQuick3D 1.0
|
||||
IconGizmo {
|
||||
id: lightGizmo
|
||||
|
||||
iconSource: targetNode instanceof DirectionalLight
|
||||
? "qrc:///qtquickplugin/mockfiles/images/directional_light_gradient.png"
|
||||
: targetNode instanceof AreaLight
|
||||
? "qrc:///qtquickplugin/mockfiles/images/area_light_gradient.png"
|
||||
: "qrc:///qtquickplugin/mockfiles/images/point_light_gradient.png"
|
||||
iconSource: targetNode
|
||||
? targetNode instanceof DirectionalLight
|
||||
? "qrc:///qtquickplugin/mockfiles/images/directional_light_gradient.png"
|
||||
: targetNode instanceof AreaLight
|
||||
? "qrc:///qtquickplugin/mockfiles/images/area_light_gradient.png"
|
||||
: "qrc:///qtquickplugin/mockfiles/images/point_light_gradient.png"
|
||||
: "qrc:///qtquickplugin/mockfiles/images/point_light_gradient.png"
|
||||
|
||||
overlayColor: targetNode.color
|
||||
overlayColor: targetNode ? targetNode.color : "transparent"
|
||||
}
|
||||
|
65
share/qtcreator/qml/qmlpuppet/mockfiles/SelectionBox.qml
Normal file
65
share/qtcreator/qml/qmlpuppet/mockfiles/SelectionBox.qml
Normal file
@@ -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 2.0
|
||||
import QtQuick3D 1.0
|
||||
import SelectionBoxGeometry 1.0
|
||||
|
||||
Node {
|
||||
id: selectionBox
|
||||
|
||||
property View3D view3D
|
||||
property Node targetNode: null
|
||||
|
||||
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.vector3d(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)
|
||||
orientation: selectionBox.targetNode ? selectionBox.targetNode.orientation : Node.LeftHanded
|
||||
rotationOrder: selectionBox.targetNode ? selectionBox.targetNode.rotationOrder : Node.YXZ
|
||||
|
||||
visible: selectionBox.targetNode && selectionBox.targetNode instanceof Model
|
||||
|
||||
materials: [
|
||||
DefaultMaterial {
|
||||
emissiveColor: "#e5009e"
|
||||
lighting: DefaultMaterial.NoLighting
|
||||
cullingMode: Material.DisableCulling
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@@ -1,9 +1,11 @@
|
||||
HEADERS += $$PWD/generalhelper.h \
|
||||
$$PWD/mousearea3d.h \
|
||||
$$PWD/camerageometry.h \
|
||||
$$PWD/gridgeometry.h
|
||||
$$PWD/gridgeometry.h \
|
||||
$$PWD/selectionboxgeometry.h
|
||||
|
||||
SOURCES += $$PWD/generalhelper.cpp \
|
||||
$$PWD/mousearea3d.cpp \
|
||||
$$PWD/camerageometry.cpp \
|
||||
$$PWD/gridgeometry.cpp
|
||||
$$PWD/gridgeometry.cpp \
|
||||
$$PWD/selectionboxgeometry.cpp
|
||||
|
@@ -0,0 +1,216 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef QUICK3D_MODULE
|
||||
|
||||
#include "selectionboxgeometry.h"
|
||||
|
||||
#include <QtQuick3DRuntimeRender/private/qssgrendergeometry_p.h>
|
||||
#include <QtQuick3DRuntimeRender/private/qssgrendermodel_p.h>
|
||||
#include <QtQuick3DRuntimeRender/private/qssgrendercontextcore_p.h>
|
||||
#include <QtQuick3DRuntimeRender/private/qssgrenderbuffermanager_p.h>
|
||||
#include <QtQuick3DUtils/private/qssgbounds3_p.h>
|
||||
#include <QtQuick3D/private/qquick3dmodel_p.h>
|
||||
#include <QtQuick3D/private/qquick3dobject_p_p.h>
|
||||
#include <QtQuick/qquickwindow.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
namespace Internal {
|
||||
|
||||
SelectionBoxGeometry::SelectionBoxGeometry()
|
||||
: QQuick3DGeometry()
|
||||
{
|
||||
}
|
||||
|
||||
SelectionBoxGeometry::~SelectionBoxGeometry()
|
||||
{
|
||||
}
|
||||
|
||||
QQuick3DNode *SelectionBoxGeometry::targetNode() const
|
||||
{
|
||||
return m_targetNode;
|
||||
}
|
||||
|
||||
QQuick3DNode *SelectionBoxGeometry::rootNode() const
|
||||
{
|
||||
return m_rootNode;
|
||||
}
|
||||
|
||||
QQuick3DViewport *SelectionBoxGeometry::view3D() const
|
||||
{
|
||||
return m_view3D;
|
||||
}
|
||||
|
||||
void SelectionBoxGeometry::setTargetNode(QQuick3DNode *targetNode)
|
||||
{
|
||||
if (m_targetNode == targetNode)
|
||||
return;
|
||||
|
||||
if (m_targetNode)
|
||||
m_targetNode->disconnect(this);
|
||||
m_targetNode = targetNode;
|
||||
|
||||
if (auto model = qobject_cast<QQuick3DModel *>(m_targetNode)) {
|
||||
QObject::connect(model, &QQuick3DModel::sourceChanged,
|
||||
this, &SelectionBoxGeometry::update, Qt::QueuedConnection);
|
||||
QObject::connect(model, &QQuick3DModel::geometryChanged,
|
||||
this, &SelectionBoxGeometry::update, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
emit targetNodeChanged();
|
||||
update();
|
||||
}
|
||||
|
||||
void SelectionBoxGeometry::setRootNode(QQuick3DNode *rootNode)
|
||||
{
|
||||
if (m_rootNode == rootNode)
|
||||
return;
|
||||
|
||||
m_rootNode = rootNode;
|
||||
|
||||
emit rootNodeChanged();
|
||||
update();
|
||||
}
|
||||
|
||||
void SelectionBoxGeometry::setView3D(QQuick3DViewport *view)
|
||||
{
|
||||
if (m_view3D == view)
|
||||
return;
|
||||
|
||||
m_view3D = view;
|
||||
|
||||
emit view3DChanged();
|
||||
update();
|
||||
}
|
||||
|
||||
QSSGRenderGraphObject *SelectionBoxGeometry::updateSpatialNode(QSSGRenderGraphObject *node)
|
||||
{
|
||||
node = QQuick3DGeometry::updateSpatialNode(node);
|
||||
QSSGRenderGeometry *geometry = static_cast<QSSGRenderGeometry *>(node);
|
||||
|
||||
geometry->clear();
|
||||
|
||||
QByteArray vertexData;
|
||||
QByteArray indexData;
|
||||
|
||||
QVector3D minBounds(-100.f, -100.f, -100.f);
|
||||
QVector3D maxBounds(100.f, 100.f, 100.f);
|
||||
QVector3D extents;
|
||||
|
||||
if (m_targetNode) {
|
||||
auto rootPriv = QQuick3DObjectPrivate::get(m_rootNode);
|
||||
auto targetPriv = QQuick3DObjectPrivate::get(m_targetNode);
|
||||
auto rootRN = static_cast<QSSGRenderNode *>(rootPriv->spatialNode);
|
||||
auto targetRN = static_cast<QSSGRenderNode *>(targetPriv->spatialNode);
|
||||
if (rootRN && targetRN) {
|
||||
// Explicitly set local transform of root node to target node parent's global transform
|
||||
// to avoid having to reparent the selection box. This has to be done directly on render
|
||||
// nodes.
|
||||
targetRN->parent->calculateGlobalVariables();
|
||||
QMatrix4x4 m = targetRN->parent->globalTransform;
|
||||
rootRN->localTransform = m;
|
||||
rootRN->markDirty(QSSGRenderNode::TransformDirtyFlag::TransformNotDirty);
|
||||
rootRN->calculateGlobalVariables();
|
||||
}
|
||||
if (auto modelNode = qobject_cast<QQuick3DModel *>(m_targetNode)) {
|
||||
auto nodePriv = QQuick3DObjectPrivate::get(m_targetNode);
|
||||
if (auto renderModel = static_cast<QSSGRenderModel *>(nodePriv->spatialNode)) {
|
||||
QWindow *window = static_cast<QWindow *>(m_view3D->window());
|
||||
if (window) {
|
||||
auto context = QSSGRenderContextInterface::getRenderContextInterface(
|
||||
quintptr(window));
|
||||
if (!context.isNull()) {
|
||||
auto bufferManager = context->bufferManager();
|
||||
QSSGBounds3 bounds = renderModel->getModelBounds(bufferManager);
|
||||
QVector3D center = bounds.center();
|
||||
extents = bounds.extents();
|
||||
minBounds = center - extents;
|
||||
maxBounds = center + extents;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust bounds to reduce targetNode pixels obscuring the selection box
|
||||
extents /= 1000.f;
|
||||
minBounds -= extents;
|
||||
maxBounds += extents;
|
||||
|
||||
fillVertexData(vertexData, indexData, minBounds, maxBounds);
|
||||
|
||||
geometry->addAttribute(QSSGRenderGeometry::Attribute::PositionSemantic, 0,
|
||||
QSSGRenderGeometry::Attribute::ComponentType::F32Type);
|
||||
geometry->addAttribute(QSSGRenderGeometry::Attribute::IndexSemantic, 0,
|
||||
QSSGRenderGeometry::Attribute::ComponentType::U16Type);
|
||||
geometry->setStride(12);
|
||||
geometry->setVertexData(vertexData);
|
||||
geometry->setIndexData(indexData);
|
||||
geometry->setPrimitiveType(QSSGRenderGeometry::Lines);
|
||||
geometry->setBounds(minBounds, maxBounds);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
void SelectionBoxGeometry::fillVertexData(QByteArray &vertexData, QByteArray &indexData,
|
||||
const QVector3D &minBounds, const QVector3D &maxBounds)
|
||||
{
|
||||
const int vertexSize = int(sizeof(float)) * 8 * 3; // 8 vertices, 3 floats/vert
|
||||
vertexData.resize(vertexSize);
|
||||
const int indexSize = int(sizeof(quint16)) * 12 * 2; // 12 lines, 2 vert/line
|
||||
indexData.resize(indexSize);
|
||||
|
||||
auto dataPtr = reinterpret_cast<float *>(vertexData.data());
|
||||
auto indexPtr = reinterpret_cast<quint16 *>(indexData.data());
|
||||
|
||||
*dataPtr++ = maxBounds.x(); *dataPtr++ = maxBounds.y(); *dataPtr++ = maxBounds.z();
|
||||
*dataPtr++ = minBounds.x(); *dataPtr++ = maxBounds.y(); *dataPtr++ = maxBounds.z();
|
||||
*dataPtr++ = minBounds.x(); *dataPtr++ = minBounds.y(); *dataPtr++ = maxBounds.z();
|
||||
*dataPtr++ = maxBounds.x(); *dataPtr++ = minBounds.y(); *dataPtr++ = maxBounds.z();
|
||||
*dataPtr++ = maxBounds.x(); *dataPtr++ = maxBounds.y(); *dataPtr++ = minBounds.z();
|
||||
*dataPtr++ = minBounds.x(); *dataPtr++ = maxBounds.y(); *dataPtr++ = minBounds.z();
|
||||
*dataPtr++ = minBounds.x(); *dataPtr++ = minBounds.y(); *dataPtr++ = minBounds.z();
|
||||
*dataPtr++ = maxBounds.x(); *dataPtr++ = minBounds.y(); *dataPtr++ = minBounds.z();
|
||||
|
||||
*indexPtr++ = 0; *indexPtr++ = 1;
|
||||
*indexPtr++ = 1; *indexPtr++ = 2;
|
||||
*indexPtr++ = 2; *indexPtr++ = 3;
|
||||
*indexPtr++ = 3; *indexPtr++ = 0;
|
||||
|
||||
*indexPtr++ = 0; *indexPtr++ = 4;
|
||||
*indexPtr++ = 1; *indexPtr++ = 5;
|
||||
*indexPtr++ = 2; *indexPtr++ = 6;
|
||||
*indexPtr++ = 3; *indexPtr++ = 7;
|
||||
|
||||
*indexPtr++ = 4; *indexPtr++ = 5;
|
||||
*indexPtr++ = 5; *indexPtr++ = 6;
|
||||
*indexPtr++ = 6; *indexPtr++ = 7;
|
||||
*indexPtr++ = 7; *indexPtr++ = 4;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // QUICK3D_MODULE
|
@@ -0,0 +1,79 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef QUICK3D_MODULE
|
||||
|
||||
#include <QtQuick3D/private/qquick3dnode_p.h>
|
||||
#include <QtQuick3D/private/qquick3dgeometry_p.h>
|
||||
#include <QtQuick3D/private/qquick3dviewport_p.h>
|
||||
|
||||
namespace QmlDesigner {
|
||||
namespace Internal {
|
||||
|
||||
class SelectionBoxGeometry : public QQuick3DGeometry
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QQuick3DNode *targetNode READ targetNode WRITE setTargetNode NOTIFY targetNodeChanged)
|
||||
Q_PROPERTY(QQuick3DNode *rootNode READ rootNode WRITE setRootNode NOTIFY rootNodeChanged)
|
||||
Q_PROPERTY(QQuick3DViewport *view3D READ view3D WRITE setView3D NOTIFY view3DChanged)
|
||||
|
||||
public:
|
||||
SelectionBoxGeometry();
|
||||
~SelectionBoxGeometry() override;
|
||||
|
||||
QQuick3DNode *targetNode() const;
|
||||
QQuick3DNode *rootNode() const;
|
||||
QQuick3DViewport *view3D() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void setTargetNode(QQuick3DNode *targetNode);
|
||||
void setRootNode(QQuick3DNode *rootNode);
|
||||
void setView3D(QQuick3DViewport *view);
|
||||
|
||||
Q_SIGNALS:
|
||||
void targetNodeChanged();
|
||||
void rootNodeChanged();
|
||||
void view3DChanged();
|
||||
|
||||
protected:
|
||||
QSSGRenderGraphObject *updateSpatialNode(QSSGRenderGraphObject *node) override;
|
||||
|
||||
private:
|
||||
void fillVertexData(QByteArray &vertexData, QByteArray &indexData,
|
||||
const QVector3D &minBounds, const QVector3D &maxBounds);
|
||||
|
||||
QQuick3DNode *m_targetNode = nullptr;
|
||||
QQuick3DViewport *m_view3D = nullptr;
|
||||
QQuick3DNode *m_rootNode = nullptr;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
QML_DECLARE_TYPE(QmlDesigner::Internal::SelectionBoxGeometry)
|
||||
|
||||
#endif // QUICK3D_MODULE
|
@@ -66,6 +66,7 @@
|
||||
#include "../editor3d/mousearea3d.h"
|
||||
#include "../editor3d/camerageometry.h"
|
||||
#include "../editor3d/gridgeometry.h"
|
||||
#include "../editor3d/selectionboxgeometry.h"
|
||||
|
||||
#include <designersupportdelegate.h>
|
||||
|
||||
@@ -110,6 +111,7 @@ QObject *Qt5InformationNodeInstanceServer::createEditView3D(QQmlEngine *engine)
|
||||
qmlRegisterType<QmlDesigner::Internal::MouseArea3D>("MouseArea3D", 1, 0, "MouseArea3D");
|
||||
qmlRegisterType<QmlDesigner::Internal::CameraGeometry>("CameraGeometry", 1, 0, "CameraGeometry");
|
||||
qmlRegisterType<QmlDesigner::Internal::GridGeometry>("GridGeometry", 1, 0, "GridGeometry");
|
||||
qmlRegisterType<QmlDesigner::Internal::SelectionBoxGeometry>("SelectionBoxGeometry", 1, 0, "SelectionBoxGeometry");
|
||||
#endif
|
||||
|
||||
QQmlComponent component(engine, QUrl("qrc:/qtquickplugin/mockfiles/EditView3D.qml"));
|
||||
|
@@ -26,6 +26,7 @@
|
||||
<file>mockfiles/ToolBarButton.qml</file>
|
||||
<file>mockfiles/RotateGizmo.qml</file>
|
||||
<file>mockfiles/RotateRing.qml</file>
|
||||
<file>mockfiles/SelectionBox.qml</file>
|
||||
<file>mockfiles/meshes/arrow.mesh</file>
|
||||
<file>mockfiles/meshes/scalerod.mesh</file>
|
||||
<file>mockfiles/meshes/ring.mesh</file>
|
||||
|
@@ -112,6 +112,7 @@ extend_qtc_executable(qml2puppet
|
||||
mousearea3d.cpp mousearea3d.h
|
||||
camerageometry.cpp camerageometry.h
|
||||
gridgeometry.cpp gridgeometry.h
|
||||
selectionboxgeometry.cpp selectionboxgeometry.h
|
||||
)
|
||||
|
||||
extend_qtc_executable(qml2puppet
|
||||
|
@@ -205,6 +205,8 @@ QtcTool {
|
||||
"editor3d/camerageometry.h",
|
||||
"editor3d/gridgeometry.cpp",
|
||||
"editor3d/gridgeometry.h",
|
||||
"editor3d/selectionboxgeometry.cpp",
|
||||
"editor3d/selectionboxgeometry.h",
|
||||
"qml2puppetmain.cpp",
|
||||
]
|
||||
}
|
||||
|
Reference in New Issue
Block a user