QmlDesigner: Properly update 3D edit view cameras and lights

Now edit view will create and remove cameras and light gizmos properly
when cameras and lights are added or deleted.

Change-Id: I858752c1410f3a40ea2adaf538c281aaee94ec58
Fixes: QDS-1267
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Miikka Heikkinen
2019-12-11 16:00:28 +02:00
parent f29a4440fe
commit eb09e814db
5 changed files with 57 additions and 26 deletions

View File

@@ -127,6 +127,15 @@ Window {
function addLightGizmo(obj)
{
// Insert into first available gizmo
for (var i = 0; i < lightGizmos.length; ++i) {
if (!lightGizmos[i].targetNode) {
lightGizmos[i].targetNode = obj;
return;
}
}
// No free gizmos available, create a new one
var component = Qt.createComponent("LightGizmo.qml");
if (component.status === Component.Ready) {
var gizmo = component.createObject(overlayScene,
@@ -140,6 +149,14 @@ Window {
function addCameraGizmo(obj)
{
// Insert into first available gizmo
for (var i = 0; i < cameraGizmos.length; ++i) {
if (!cameraGizmos[i].targetNode) {
cameraGizmos[i].targetNode = obj;
return;
}
}
// No free gizmos available, create a new one
var component = Qt.createComponent("CameraGizmo.qml");
if (component.status === Component.Ready) {
var geometryName = _generalHelper.generateUniqueName("CameraGeometry");

View File

@@ -148,16 +148,19 @@ void CameraGeometry::fillVertexData(QByteArray &vertexData, QByteArray &indexDat
auto dataPtr = reinterpret_cast<float *>(vertexData.data());
auto indexPtr = reinterpret_cast<quint16 *>(indexData.data());
QMatrix4x4 m;
QSSGRenderCamera *camera = m_camera->cameraNode();
if (qobject_cast<QQuick3DOrthographicCamera *>(m_camera)) {
// For some reason ortho cameras show double what projection suggests,
// so give them doubled viewport to match visualization to actual camera view
camera->calculateProjection(QRectF(0, 0, m_viewPortRect.width() * 2.0,
m_viewPortRect.height() * 2.0));
} else {
camera->calculateProjection(m_viewPortRect);
if (camera) {
if (qobject_cast<QQuick3DOrthographicCamera *>(m_camera)) {
// For some reason ortho cameras show double what projection suggests,
// so give them doubled viewport to match visualization to actual camera view
camera->calculateProjection(QRectF(0, 0, m_viewPortRect.width() * 2.0,
m_viewPortRect.height() * 2.0));
} else {
camera->calculateProjection(m_viewPortRect);
}
m = camera->projection.inverted();
}
const QMatrix4x4 m = camera->projection.inverted();
const QVector3D farTopLeft = m * QVector3D(1.f, -1.f, 1.f);
const QVector3D farBottomRight = m * QVector3D(-1.f, 1.f, 1.f);

View File

@@ -155,7 +155,7 @@ public slots:
void emitParentChanged(QObject *child);
protected:
QList<ServerNodeInstance> createInstances(const QVector<InstanceContainer> &container);
virtual QList<ServerNodeInstance> createInstances(const QVector<InstanceContainer> &container);
void reparentInstances(const QVector<ReparentContainer> &containerVector);
Internal::ChildrenChangeEventFilter *childrenChangeEventFilter();

View File

@@ -409,6 +409,17 @@ void Qt5InformationNodeInstanceServer::modifyProperties(
nodeInstanceClient()->valuesModified(createValuesModifiedCommand(properties));
}
QList<ServerNodeInstance> Qt5InformationNodeInstanceServer::createInstances(
const QVector<InstanceContainer> &container)
{
const auto createdInstances = NodeInstanceServer::createInstances(container);
if (m_editView3D)
createCameraAndLightGizmos(createdInstances);
return createdInstances;
}
void Qt5InformationNodeInstanceServer::handleObjectPropertyChangeTimeout()
{
modifyVariantValue(m_changedNode, m_changedProperty,
@@ -448,16 +459,27 @@ QObject *Qt5InformationNodeInstanceServer::findRootNodeOf3DViewport(
return nullptr;
}
void Qt5InformationNodeInstanceServer::findCamerasAndLights(
const QList<ServerNodeInstance> &instanceList,
QObjectList &cameras, QObjectList &lights) const
void Qt5InformationNodeInstanceServer::createCameraAndLightGizmos(
const QList<ServerNodeInstance> &instanceList) const
{
QObjectList cameras;
QObjectList lights;
for (const ServerNodeInstance &instance : instanceList) {
if (instance.isSubclassOf("QQuick3DCamera"))
cameras << instance.internalObject();
else if (instance.isSubclassOf("QQuick3DAbstractLight"))
lights << instance.internalObject();
}
for (auto &obj : qAsConst(cameras)) {
QMetaObject::invokeMethod(m_editView3D, "addCameraGizmo",
Q_ARG(QVariant, objectToVariant(obj)));
}
for (auto &obj : qAsConst(lights)) {
QMetaObject::invokeMethod(m_editView3D, "addLightGizmo",
Q_ARG(QVariant, objectToVariant(obj)));
}
}
ServerNodeInstance Qt5InformationNodeInstanceServer::findViewPort(
@@ -506,18 +528,7 @@ void Qt5InformationNodeInstanceServer::setup3DEditView(const QList<ServerNodeIns
updateViewPortRect();
}
// Create camera and light gizmos
QObjectList cameras;
QObjectList lights;
findCamerasAndLights(instanceList, cameras, lights);
for (auto &obj : qAsConst(cameras)) {
QMetaObject::invokeMethod(m_editView3D, "addCameraGizmo",
Q_ARG(QVariant, objectToVariant(obj)));
}
for (auto &obj : qAsConst(lights)) {
QMetaObject::invokeMethod(m_editView3D, "addLightGizmo",
Q_ARG(QVariant, objectToVariant(obj)));
}
createCameraAndLightGizmos(instanceList);
}
}

View File

@@ -67,6 +67,7 @@ protected:
bool isDirtyRecursiveForParentInstances(QQuickItem *item) const;
void selectInstances(const QList<ServerNodeInstance> &instanceList);
void modifyProperties(const QVector<InstancePropertyValueTriple> &properties);
QList<ServerNodeInstance> createInstances(const QVector<InstanceContainer> &container) override;
private:
void handleObjectPropertyChangeTimeout();
@@ -74,8 +75,7 @@ private:
QObject *createEditView3D(QQmlEngine *engine);
void setup3DEditView(const QList<ServerNodeInstance> &instanceList);
QObject *findRootNodeOf3DViewport(const QList<ServerNodeInstance> &instanceList) const;
void findCamerasAndLights( const QList<ServerNodeInstance> &instanceList,
QObjectList &cameras, QObjectList &lights) const;
void createCameraAndLightGizmos(const QList<ServerNodeInstance> &instanceList) const;
ServerNodeInstance findViewPort(const QList<ServerNodeInstance> &instanceList);
QVector<InstancePropertyValueTriple> vectorToPropertyValue(const ServerNodeInstance &instance,
const PropertyName &propertyName,