forked from qt-creator/qt-creator
QmlDesigner: Update light gizmos
Directional light model was made constant size, as it doesn't have actual physical presence. Spot light cone now shows the cone angle correctly and the length of the cone is calculated so that 5% of the brightness reaches the center of the cone bottom. Area light rectangle matches the area of the light. Point light mesh changed to three perpendicular circles. Same formula for size of the circles used as for spotlight length. All light types share a common brightness indicator arrow. Task-number: QDS-2037 Change-Id: I534dbcda9cfa2a7768c2537868ba83818979b250 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
55
share/qtcreator/qml/qmlpuppet/mockfiles/AdjustableArrow.qml
Normal file
55
share/qtcreator/qml/qmlpuppet/mockfiles/AdjustableArrow.qml
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 2.0
|
||||||
|
import QtQuick3D 1.15
|
||||||
|
import LineGeometry 1.0
|
||||||
|
|
||||||
|
Arrow {
|
||||||
|
id: arrowRoot
|
||||||
|
|
||||||
|
property real length: 10
|
||||||
|
|
||||||
|
source: ""
|
||||||
|
|
||||||
|
Model {
|
||||||
|
geometry: LineGeometry {
|
||||||
|
id: lineGeometry
|
||||||
|
name: "Edit 3D ScalableArrow"
|
||||||
|
startPos: Qt.vector3d(0, 0, 0)
|
||||||
|
endPos: Qt.vector3d(0, 1, 0)
|
||||||
|
}
|
||||||
|
materials: [ arrowRoot.material ]
|
||||||
|
scale: Qt.vector3d(1, arrowRoot.length, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
Model {
|
||||||
|
id: arrowHead
|
||||||
|
source: "#Cone"
|
||||||
|
materials: [ arrowRoot.material ]
|
||||||
|
y: arrowRoot.length
|
||||||
|
scale: Qt.vector3d(0.02, 0.035, 0.02)
|
||||||
|
}
|
||||||
|
}
|
@@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
import QtQuick 2.0
|
import QtQuick 2.0
|
||||||
import QtQuick3D 1.15
|
import QtQuick3D 1.15
|
||||||
import MouseArea3D 1.0
|
|
||||||
|
|
||||||
DirectionalDraggable {
|
DirectionalDraggable {
|
||||||
id: arrow
|
id: arrow
|
||||||
|
@@ -36,6 +36,7 @@ Model {
|
|||||||
property bool dragging: mouseAreaYZ.dragging || mouseAreaXZ.dragging
|
property bool dragging: mouseAreaYZ.dragging || mouseAreaXZ.dragging
|
||||||
property bool active: false
|
property bool active: false
|
||||||
property MouseArea3D dragHelper: null
|
property MouseArea3D dragHelper: null
|
||||||
|
property alias material: material
|
||||||
|
|
||||||
readonly property bool hovering: mouseAreaYZ.hovering || mouseAreaXZ.hovering
|
readonly property bool hovering: mouseAreaYZ.hovering || mouseAreaXZ.hovering
|
||||||
|
|
||||||
@@ -47,12 +48,14 @@ Model {
|
|||||||
signal dragged(var mouseArea, vector3d sceneRelativeDistance, real relativeDistance)
|
signal dragged(var mouseArea, vector3d sceneRelativeDistance, real relativeDistance)
|
||||||
signal released(var mouseArea, vector3d sceneRelativeDistance, real relativeDistance)
|
signal released(var mouseArea, vector3d sceneRelativeDistance, real relativeDistance)
|
||||||
|
|
||||||
materials: DefaultMaterial {
|
DefaultMaterial {
|
||||||
id: material
|
id: material
|
||||||
emissiveColor: "white"
|
emissiveColor: "white"
|
||||||
lighting: DefaultMaterial.NoLighting
|
lighting: DefaultMaterial.NoLighting
|
||||||
}
|
}
|
||||||
|
|
||||||
|
materials: [ material ]
|
||||||
|
|
||||||
function handlePressed(mouseArea, planePos)
|
function handlePressed(mouseArea, planePos)
|
||||||
{
|
{
|
||||||
if (!targetNode)
|
if (!targetNode)
|
||||||
|
@@ -54,7 +54,7 @@ Item {
|
|||||||
property Node selectedNode: null // This is non-null only in single selection case
|
property Node selectedNode: null // This is non-null only in single selection case
|
||||||
property var selectedNodes: [] // All selected nodes
|
property var selectedNodes: [] // All selected nodes
|
||||||
|
|
||||||
property var lightGizmos: []
|
property var lightIconGizmos: []
|
||||||
property var cameraGizmos: []
|
property var cameraGizmos: []
|
||||||
property var selectionBoxes: []
|
property var selectionBoxes: []
|
||||||
property rect viewPortRect: Qt.rect(0, 0, 1000, 1000)
|
property rect viewPortRect: Qt.rect(0, 0, 1000, 1000)
|
||||||
@@ -278,29 +278,25 @@ Item {
|
|||||||
function addLightGizmo(scene, obj)
|
function addLightGizmo(scene, obj)
|
||||||
{
|
{
|
||||||
// Insert into first available gizmo
|
// Insert into first available gizmo
|
||||||
for (var i = 0; i < lightGizmos.length; ++i) {
|
for (var i = 0; i < lightIconGizmos.length; ++i) {
|
||||||
if (!lightGizmos[i].targetNode) {
|
if (!lightIconGizmos[i].targetNode) {
|
||||||
lightGizmos[i].scene = scene;
|
lightIconGizmos[i].scene = scene;
|
||||||
lightGizmos[i].targetNode = obj;
|
lightIconGizmos[i].targetNode = obj;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// No free gizmos available, create a new one
|
// No free gizmos available, create a new one
|
||||||
var gizmoComponent = Qt.createComponent("LightGizmo.qml");
|
var gizmoComponent = Qt.createComponent("LightIconGizmo.qml");
|
||||||
var modelComponent = Qt.createComponent("LightModel.qml");
|
if (gizmoComponent.status === Component.Ready) {
|
||||||
if (gizmoComponent.status === Component.Ready && modelComponent.status === Component.Ready) {
|
|
||||||
var geometryName = _generalHelper.generateUniqueName("LightGeometry");
|
|
||||||
var model = modelComponent.createObject(overlayScene, {"geometryName": geometryName});
|
|
||||||
var gizmo = gizmoComponent.createObject(overlayView,
|
var gizmo = gizmoComponent.createObject(overlayView,
|
||||||
{"view3D": overlayView, "targetNode": obj,
|
{"view3D": overlayView, "targetNode": obj,
|
||||||
"selectedNodes": selectedNodes, "scene": scene,
|
"selectedNodes": selectedNodes, "scene": scene,
|
||||||
"activeScene": activeScene});
|
"activeScene": activeScene});
|
||||||
lightGizmos[lightGizmos.length] = gizmo;
|
lightIconGizmos[lightIconGizmos.length] = gizmo;
|
||||||
gizmo.clicked.connect(handleObjectClicked);
|
gizmo.clicked.connect(handleObjectClicked);
|
||||||
gizmo.selectedNodes = Qt.binding(function() {return selectedNodes;});
|
gizmo.selectedNodes = Qt.binding(function() {return selectedNodes;});
|
||||||
gizmo.activeScene = Qt.binding(function() {return activeScene;});
|
gizmo.activeScene = Qt.binding(function() {return activeScene;});
|
||||||
gizmo.connectModel(model);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,10 +334,10 @@ Item {
|
|||||||
|
|
||||||
function releaseLightGizmo(obj)
|
function releaseLightGizmo(obj)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < lightGizmos.length; ++i) {
|
for (var i = 0; i < lightIconGizmos.length; ++i) {
|
||||||
if (lightGizmos[i].targetNode === obj) {
|
if (lightIconGizmos[i].targetNode === obj) {
|
||||||
lightGizmos[i].scene = null;
|
lightIconGizmos[i].scene = null;
|
||||||
lightGizmos[i].targetNode = null;
|
lightIconGizmos[i].targetNode = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -360,9 +356,9 @@ Item {
|
|||||||
|
|
||||||
function updateLightGizmoScene(scene, obj)
|
function updateLightGizmoScene(scene, obj)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < lightGizmos.length; ++i) {
|
for (var i = 0; i < lightIconGizmos.length; ++i) {
|
||||||
if (lightGizmos[i].targetNode === obj) {
|
if (lightIconGizmos[i].targetNode === obj) {
|
||||||
lightGizmos[i].scene = scene;
|
lightIconGizmos[i].scene = scene;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -455,6 +451,13 @@ Item {
|
|||||||
onRotateChange: viewRoot.changeObjectProperty(viewRoot.selectedNode, "eulerRotation")
|
onRotateChange: viewRoot.changeObjectProperty(viewRoot.selectedNode, "eulerRotation")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LightGizmo {
|
||||||
|
id: lightGizmo
|
||||||
|
targetNode: viewRoot.selectedNode
|
||||||
|
view3D: overlayView
|
||||||
|
dragHelper: gizmoDragHelper
|
||||||
|
}
|
||||||
|
|
||||||
AutoScaleHelper {
|
AutoScaleHelper {
|
||||||
id: autoScale
|
id: autoScale
|
||||||
view3D: overlayView
|
view3D: overlayView
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2019 The Qt Company Ltd.
|
** Copyright (C) 2020 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of Qt Creator.
|
** This file is part of Qt Creator.
|
||||||
@@ -25,45 +25,138 @@
|
|||||||
|
|
||||||
import QtQuick 2.0
|
import QtQuick 2.0
|
||||||
import QtQuick3D 1.15
|
import QtQuick3D 1.15
|
||||||
|
import MouseArea3D 1.0
|
||||||
|
import LightGeometry 1.0
|
||||||
|
|
||||||
IconGizmo {
|
Node {
|
||||||
id: lightGizmo
|
id: lightGizmo
|
||||||
|
|
||||||
property Model lightModel: null
|
property View3D view3D
|
||||||
property color overlayColor: targetNode ? targetNode.color : "transparent"
|
property Node targetNode: null
|
||||||
|
property MouseArea3D dragHelper: null
|
||||||
iconSource: targetNode
|
property color color: Qt.rgba(1, 1, 0, 1)
|
||||||
? targetNode instanceof DirectionalLight
|
property real brightnessScale: targetNode ? Math.max(1.0, 1.0 + targetNode.brightness) : 100
|
||||||
? "image://IconGizmoImageProvider/directional.png:" + overlayColor
|
property real fadeScale: {
|
||||||
: targetNode instanceof AreaLight
|
// Value indicates area where intensity is above certain percent of total brightness.
|
||||||
? "image://IconGizmoImageProvider/area.png:" + overlayColor
|
if (lightGizmo.targetNode instanceof SpotLight || lightGizmo.targetNode instanceof PointLight) {
|
||||||
: targetNode instanceof PointLight
|
var l = targetNode.linearFade;
|
||||||
? "image://IconGizmoImageProvider/point.png:" + overlayColor
|
var q = targetNode.quadraticFade;
|
||||||
: "image://IconGizmoImageProvider/spot.png:" + overlayColor
|
var c = targetNode.constantFade;
|
||||||
: "image://IconGizmoImageProvider/point.png:" + overlayColor
|
var d = 20; // divisor to target intensity value. E.g. 20 = 1/20 = 5%
|
||||||
|
if (l === 0 && q === 0)
|
||||||
function connectModel(model)
|
l = 1;
|
||||||
{
|
// Solved from equation in shader:
|
||||||
lightModel = model;
|
// 1 / d = 1 / (c + (l + q * dist) * dist);
|
||||||
|
if (q === 0)
|
||||||
model.selected = selected;
|
return 100 * Math.max(((d - c) / l), 1);
|
||||||
model.selected = Qt.binding(function() {return selected;});
|
else
|
||||||
|
return 100 * ((Math.sqrt(4 * q * (d - c) + (l * l)) - l) / (2 * q));
|
||||||
model.scene = scene;
|
} else {
|
||||||
model.scene = Qt.binding(function() {return scene;});
|
return 100;
|
||||||
|
}
|
||||||
model.targetNode = targetNode;
|
}
|
||||||
model.targetNode = Qt.binding(function() {return targetNode;});
|
|
||||||
|
position: targetNode ? targetNode.scenePosition : Qt.vector3d(0, 0, 0)
|
||||||
model.color = lightGizmo.overlayColor;
|
visible: lightGizmo.targetNode instanceof SpotLight
|
||||||
model.color = Qt.binding(function() {return lightGizmo.overlayColor;});
|
|| lightGizmo.targetNode instanceof AreaLight
|
||||||
|
|| lightGizmo.targetNode instanceof DirectionalLight
|
||||||
model.visible = visible;
|
|| lightGizmo.targetNode instanceof PointLight
|
||||||
model.visible = Qt.binding(function() {return visible;});
|
|
||||||
}
|
AutoScaleHelper {
|
||||||
|
id: autoScale
|
||||||
onActiveSceneChanged: {
|
view3D: lightGizmo.view3D
|
||||||
if (lightModel && activeScene == scene)
|
}
|
||||||
lightModel.updateGeometry();
|
|
||||||
|
Node {
|
||||||
|
rotation: !lightGizmo.targetNode ? Qt.quaternion(1, 0, 0, 0)
|
||||||
|
: lightGizmo.targetNode.sceneRotation
|
||||||
|
|
||||||
|
LightModel {
|
||||||
|
id: spotModel
|
||||||
|
|
||||||
|
property real coneScale: visible
|
||||||
|
? lightGizmo.fadeScale * Math.tan(Math.PI * targetNode.coneAngle / 180)
|
||||||
|
: 1
|
||||||
|
|
||||||
|
geometryName: "Edit 3D SpotLight"
|
||||||
|
geometryType: LightGeometry.Spot
|
||||||
|
color: lightGizmo.color
|
||||||
|
visible: lightGizmo.targetNode instanceof SpotLight
|
||||||
|
scale: Qt.vector3d(coneScale, coneScale, lightGizmo.fadeScale)
|
||||||
|
}
|
||||||
|
Node {
|
||||||
|
visible: lightGizmo.targetNode instanceof SpotLight
|
||||||
|
SpotLightHandle {
|
||||||
|
id: sphereHandle1
|
||||||
|
view3D: lightGizmo.view3D
|
||||||
|
material: lightMaterial
|
||||||
|
position: Qt.vector3d(0, spotModel.scale.y, -spotModel.scale.z)
|
||||||
|
}
|
||||||
|
SpotLightHandle {
|
||||||
|
id: sphereHandle2
|
||||||
|
view3D: lightGizmo.view3D
|
||||||
|
material: lightMaterial
|
||||||
|
position: Qt.vector3d(spotModel.scale.x, 0, -spotModel.scale.z)
|
||||||
|
}
|
||||||
|
SpotLightHandle {
|
||||||
|
id: sphereHandle3
|
||||||
|
view3D: lightGizmo.view3D
|
||||||
|
material: lightMaterial
|
||||||
|
position: Qt.vector3d(0, -spotModel.scale.y, -spotModel.scale.z)
|
||||||
|
}
|
||||||
|
SpotLightHandle {
|
||||||
|
id: sphereHandle4
|
||||||
|
view3D: lightGizmo.view3D
|
||||||
|
material: lightMaterial
|
||||||
|
position: Qt.vector3d(-spotModel.scale.x, 0, -spotModel.scale.z)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LightModel {
|
||||||
|
id: areaModel
|
||||||
|
geometryName: "Edit 3D AreaLight"
|
||||||
|
geometryType: LightGeometry.Area
|
||||||
|
color: lightGizmo.color
|
||||||
|
visible: lightGizmo.targetNode instanceof AreaLight
|
||||||
|
scale: visible ? Qt.vector3d(lightGizmo.targetNode.width / 2,
|
||||||
|
lightGizmo.targetNode.height / 2, 1)
|
||||||
|
.times(lightGizmo.targetNode.scale)
|
||||||
|
: Qt.vector3d(1, 1, 1)
|
||||||
|
}
|
||||||
|
LightModel {
|
||||||
|
id: directionalModel
|
||||||
|
geometryName: "Edit 3D DirLight"
|
||||||
|
geometryType: LightGeometry.Directional
|
||||||
|
color: lightGizmo.color
|
||||||
|
visible: lightGizmo.targetNode instanceof DirectionalLight
|
||||||
|
scale: autoScale.getScale(Qt.vector3d(50, 50, 50))
|
||||||
|
}
|
||||||
|
LightModel {
|
||||||
|
id: pointModel
|
||||||
|
geometryName: "Edit 3D PointLight"
|
||||||
|
geometryType: LightGeometry.Point
|
||||||
|
color: lightGizmo.color
|
||||||
|
visible: lightGizmo.targetNode instanceof PointLight
|
||||||
|
scale: Qt.vector3d(lightGizmo.fadeScale, lightGizmo.fadeScale, lightGizmo.fadeScale)
|
||||||
|
}
|
||||||
|
|
||||||
|
AdjustableArrow {
|
||||||
|
id: primaryArrow
|
||||||
|
eulerRotation: Qt.vector3d(-90, 0, 0)
|
||||||
|
targetNode: lightGizmo.targetNode
|
||||||
|
color: lightGizmo.color
|
||||||
|
view3D: lightGizmo.view3D
|
||||||
|
active: false
|
||||||
|
dragHelper: lightGizmo.dragHelper
|
||||||
|
scale: autoScale.getScale(Qt.vector3d(5, 5, 5))
|
||||||
|
length: lightGizmo.brightnessScale / 10
|
||||||
|
}
|
||||||
|
|
||||||
|
DefaultMaterial {
|
||||||
|
id: lightMaterial
|
||||||
|
emissiveColor: lightGizmo.color
|
||||||
|
lighting: DefaultMaterial.NoLighting
|
||||||
|
cullMode: Material.NoCulling
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
43
share/qtcreator/qml/qmlpuppet/mockfiles/LightIconGizmo.qml
Normal file
43
share/qtcreator/qml/qmlpuppet/mockfiles/LightIconGizmo.qml
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** 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 2.0
|
||||||
|
import QtQuick3D 1.15
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
@@ -30,11 +30,8 @@ import LightGeometry 1.0
|
|||||||
Model {
|
Model {
|
||||||
id: lightModel
|
id: lightModel
|
||||||
|
|
||||||
property string geometryName
|
|
||||||
property alias geometryName: lightGeometry.name // Name must be unique for each geometry
|
property alias geometryName: lightGeometry.name // Name must be unique for each geometry
|
||||||
property Node targetNode: null
|
property alias geometryType: lightGeometry.lightType
|
||||||
property Node scene: null
|
|
||||||
property bool selected: false
|
|
||||||
property color color
|
property color color
|
||||||
|
|
||||||
function updateGeometry()
|
function updateGeometry()
|
||||||
@@ -42,15 +39,13 @@ Model {
|
|||||||
lightGeometry.update();
|
lightGeometry.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
position: targetNode ? targetNode.scenePosition : Qt.vector3d(0, 0, 0)
|
|
||||||
rotation: targetNode ? targetNode.sceneRotation : Qt.quaternion(1, 0, 0, 0)
|
|
||||||
scale: Qt.vector3d(50, 50, 50)
|
scale: Qt.vector3d(50, 50, 50)
|
||||||
|
|
||||||
geometry: lightGeometry
|
geometry: lightGeometry
|
||||||
materials: [
|
materials: [
|
||||||
DefaultMaterial {
|
DefaultMaterial {
|
||||||
id: defaultMaterial
|
id: defaultMaterial
|
||||||
emissiveColor: lightModel.selected ? lightModel.color : "#555555"
|
emissiveColor: lightModel.color
|
||||||
lighting: DefaultMaterial.NoLighting
|
lighting: DefaultMaterial.NoLighting
|
||||||
cullMode: Material.NoCulling
|
cullMode: Material.NoCulling
|
||||||
}
|
}
|
||||||
@@ -58,6 +53,5 @@ Model {
|
|||||||
|
|
||||||
LightGeometry {
|
LightGeometry {
|
||||||
id: lightGeometry
|
id: lightGeometry
|
||||||
light: lightModel.scene && lightModel.targetNode ? lightModel.targetNode : null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
45
share/qtcreator/qml/qmlpuppet/mockfiles/SpotLightHandle.qml
Normal file
45
share/qtcreator/qml/qmlpuppet/mockfiles/SpotLightHandle.qml
Normal file
@@ -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 2.0
|
||||||
|
import QtQuick3D 1.15
|
||||||
|
|
||||||
|
Node {
|
||||||
|
id: handleRoot
|
||||||
|
|
||||||
|
property DefaultMaterial material
|
||||||
|
property View3D view3D
|
||||||
|
|
||||||
|
Model {
|
||||||
|
scale: autoScale.getScale(Qt.vector3d(0.1, 0.1, 0.1))
|
||||||
|
source: "#Sphere"
|
||||||
|
materials: [ handleRoot.material ]
|
||||||
|
}
|
||||||
|
|
||||||
|
AutoScaleHelper {
|
||||||
|
id: autoScale
|
||||||
|
view3D: handleRoot.view3D
|
||||||
|
}
|
||||||
|
}
|
@@ -29,10 +29,6 @@
|
|||||||
|
|
||||||
#include <QtQuick3DRuntimeRender/private/qssgrendergeometry_p.h>
|
#include <QtQuick3DRuntimeRender/private/qssgrendergeometry_p.h>
|
||||||
#include <QtQuick3DRuntimeRender/private/qssgrenderlight_p.h>
|
#include <QtQuick3DRuntimeRender/private/qssgrenderlight_p.h>
|
||||||
#include <QtQuick3D/private/qquick3darealight_p.h>
|
|
||||||
#include <QtQuick3D/private/qquick3ddirectionallight_p.h>
|
|
||||||
#include <QtQuick3D/private/qquick3dpointlight_p.h>
|
|
||||||
#include <QtQuick3D/private/qquick3dspotlight_p.h>
|
|
||||||
#include <QtCore/qmath.h>
|
#include <QtCore/qmath.h>
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
@@ -49,25 +45,25 @@ LightGeometry::~LightGeometry()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
QQuick3DAbstractLight *QmlDesigner::Internal::LightGeometry::light() const
|
LightGeometry::LightType LightGeometry::lightType() const
|
||||||
{
|
{
|
||||||
return m_light;
|
return m_lightType;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlDesigner::Internal::LightGeometry::setLight(QQuick3DAbstractLight *light)
|
void LightGeometry::setLightType(LightGeometry::LightType lightType)
|
||||||
{
|
{
|
||||||
if (m_light == light)
|
if (m_lightType == lightType)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_light = light;
|
m_lightType = lightType;
|
||||||
|
|
||||||
emit lightChanged();
|
emit lightTypeChanged();
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
QSSGRenderGraphObject *LightGeometry::updateSpatialNode(QSSGRenderGraphObject *node)
|
QSSGRenderGraphObject *LightGeometry::updateSpatialNode(QSSGRenderGraphObject *node)
|
||||||
{
|
{
|
||||||
if (!m_light)
|
if (m_lightType == LightType::Invalid)
|
||||||
return node;
|
return node;
|
||||||
|
|
||||||
node = QQuick3DGeometry::updateSpatialNode(node);
|
node = QQuick3DGeometry::updateSpatialNode(node);
|
||||||
@@ -99,28 +95,26 @@ void LightGeometry::fillVertexData(QByteArray &vertexData, QByteArray &indexData
|
|||||||
{
|
{
|
||||||
int vertexSize = 0;
|
int vertexSize = 0;
|
||||||
int indexSize = 0;
|
int indexSize = 0;
|
||||||
const int dirSegments = 12; // Segment lines in directional light circle
|
const int arc = 12; // Segment lines per cone line in spot/directional light arc
|
||||||
const int spotArc = 6; // Segment lines per cone line in spotlight arc
|
const int dirLines = 4; // Directional lines in spot/directional light
|
||||||
const int spotCone = 4; // Lines in spotlight cone
|
const quint16 segments = arc * dirLines;
|
||||||
const int pointLightDensity = 5;
|
const double segment = M_PI * 2. / double(segments);
|
||||||
|
|
||||||
if (qobject_cast<QQuick3DAreaLight *>(m_light)) {
|
if (m_lightType == LightType::Area) {
|
||||||
// Area light model is a rectangle with perpendicular lines on corners
|
// Area light model is a rectangle
|
||||||
vertexSize = int(sizeof(float)) * 3 * 8;
|
vertexSize = int(sizeof(float)) * 3 * 4;
|
||||||
indexSize = int(sizeof(quint16)) * 8 * 2;
|
indexSize = int(sizeof(quint16)) * 4 * 2;
|
||||||
} else if (qobject_cast<QQuick3DDirectionalLight *>(m_light)) {
|
} else if (m_lightType == LightType::Directional) {
|
||||||
// Directional light model is a circle with perpendicular lines on circumference vertices
|
// Directional light model is a circle with perpendicular lines on circumference vertices
|
||||||
vertexSize = int(sizeof(float)) * 3 * dirSegments * 2;
|
vertexSize = int(sizeof(float)) * 3 * (segments + dirLines);
|
||||||
indexSize = int(sizeof(quint16)) * dirSegments * 2 * 2;
|
indexSize = int(sizeof(quint16)) * (segments + dirLines) * 2;
|
||||||
} else if (qobject_cast<QQuick3DPointLight *>(m_light)) {
|
} else if (m_lightType == LightType::Point) {
|
||||||
// Point light model is a set of lines radiating from central point.
|
// Point light model is a set of three perpendicular circles
|
||||||
// We reserve more than we need so we don't have to calculate the actual need here,
|
vertexSize = int(sizeof(float)) * 3 * segments * 3;
|
||||||
// and resize later when we know the exact count.
|
indexSize = int(sizeof(quint16)) * segments * 2 * 3;
|
||||||
vertexSize = int(sizeof(float)) * 3 * pointLightDensity * pointLightDensity * 4;
|
} else if (m_lightType == LightType::Spot) {
|
||||||
indexSize = int(sizeof(quint16)) * pointLightDensity * pointLightDensity * 4;
|
vertexSize = int(sizeof(float)) * 3 * (segments + 1);
|
||||||
} else if (qobject_cast<QQuick3DSpotLight *>(m_light)) {
|
indexSize = int(sizeof(quint16)) * (segments + dirLines) * 2;
|
||||||
vertexSize = int(sizeof(float)) * 3 * (spotArc * spotCone + 1);
|
|
||||||
indexSize = int(sizeof(quint16)) * (spotArc + 1) * spotCone * 2;
|
|
||||||
}
|
}
|
||||||
vertexData.resize(vertexSize);
|
vertexData.resize(vertexSize);
|
||||||
indexData.resize(indexSize);
|
indexData.resize(indexSize);
|
||||||
@@ -128,89 +122,56 @@ void LightGeometry::fillVertexData(QByteArray &vertexData, QByteArray &indexData
|
|||||||
auto dataPtr = reinterpret_cast<float *>(vertexData.data());
|
auto dataPtr = reinterpret_cast<float *>(vertexData.data());
|
||||||
auto indexPtr = reinterpret_cast<quint16 *>(indexData.data());
|
auto indexPtr = reinterpret_cast<quint16 *>(indexData.data());
|
||||||
|
|
||||||
if (qobject_cast<QQuick3DAreaLight *>(m_light)) {
|
auto createCircle = [&](quint16 startIndex, float zVal, int xIdx, int yIdx, int zIdx) {
|
||||||
|
for (quint16 i = 0; i < segments; ++i) {
|
||||||
|
float x = float(qCos(i * segment));
|
||||||
|
float y = float(qSin(i * segment));
|
||||||
|
auto vecPtr = reinterpret_cast<QVector3D *>(dataPtr);
|
||||||
|
(*vecPtr)[xIdx] = x;
|
||||||
|
(*vecPtr)[yIdx] = y;
|
||||||
|
(*vecPtr)[zIdx] = zVal;
|
||||||
|
dataPtr += 3;
|
||||||
|
*indexPtr++ = startIndex + i; *indexPtr++ = startIndex + i + 1;
|
||||||
|
}
|
||||||
|
// Adjust the final index to complete the circle
|
||||||
|
*(indexPtr - 1) = startIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (m_lightType == LightType::Area) {
|
||||||
*dataPtr++ = -1.f; *dataPtr++ = 1.f; *dataPtr++ = 0.f;
|
*dataPtr++ = -1.f; *dataPtr++ = 1.f; *dataPtr++ = 0.f;
|
||||||
*dataPtr++ = -1.f; *dataPtr++ = -1.f; *dataPtr++ = 0.f;
|
*dataPtr++ = -1.f; *dataPtr++ = -1.f; *dataPtr++ = 0.f;
|
||||||
*dataPtr++ = 1.f; *dataPtr++ = -1.f; *dataPtr++ = 0.f;
|
*dataPtr++ = 1.f; *dataPtr++ = -1.f; *dataPtr++ = 0.f;
|
||||||
*dataPtr++ = 1.f; *dataPtr++ = 1.f; *dataPtr++ = 0.f;
|
*dataPtr++ = 1.f; *dataPtr++ = 1.f; *dataPtr++ = 0.f;
|
||||||
|
|
||||||
*dataPtr++ = -1.f; *dataPtr++ = 1.f; *dataPtr++ = -1.f;
|
|
||||||
*dataPtr++ = -1.f; *dataPtr++ = -1.f; *dataPtr++ = -1.f;
|
|
||||||
*dataPtr++ = 1.f; *dataPtr++ = -1.f; *dataPtr++ = -1.f;
|
|
||||||
*dataPtr++ = 1.f; *dataPtr++ = 1.f; *dataPtr++ = -1.f;
|
|
||||||
|
|
||||||
*indexPtr++ = 0; *indexPtr++ = 1;
|
*indexPtr++ = 0; *indexPtr++ = 1;
|
||||||
*indexPtr++ = 1; *indexPtr++ = 2;
|
*indexPtr++ = 1; *indexPtr++ = 2;
|
||||||
*indexPtr++ = 2; *indexPtr++ = 3;
|
*indexPtr++ = 2; *indexPtr++ = 3;
|
||||||
*indexPtr++ = 3; *indexPtr++ = 0;
|
*indexPtr++ = 3; *indexPtr++ = 0;
|
||||||
|
} else if (m_lightType == LightType::Directional) {
|
||||||
|
createCircle(0, 0.f, 0, 1, 2);
|
||||||
|
|
||||||
*indexPtr++ = 0; *indexPtr++ = 4;
|
// Dir lines
|
||||||
*indexPtr++ = 1; *indexPtr++ = 5;
|
for (quint16 i = 0; i < dirLines; ++i) {
|
||||||
*indexPtr++ = 2; *indexPtr++ = 6;
|
auto circlePtr = reinterpret_cast<float *>(vertexData.data()) + (3 * arc * i);
|
||||||
*indexPtr++ = 3; *indexPtr++ = 7;
|
*dataPtr++ = *circlePtr; *dataPtr++ = *(circlePtr + 1); *dataPtr++ = -3.f;
|
||||||
} else if (qobject_cast<QQuick3DDirectionalLight *>(m_light)) {
|
*indexPtr++ = i * arc;
|
||||||
const double segment = M_PI * 2. / double(dirSegments);
|
*indexPtr++ = i + segments;
|
||||||
for (quint16 i = 0; i < dirSegments; ++i) {
|
|
||||||
float x = float(qCos(i * segment));
|
|
||||||
float y = float(qSin(i * segment));
|
|
||||||
*dataPtr++ = x; *dataPtr++ = y; *dataPtr++ = 0.f;
|
|
||||||
*dataPtr++ = x; *dataPtr++ = y; *dataPtr++ = -1.f;
|
|
||||||
const quint16 base = i * 2;
|
|
||||||
*indexPtr++ = base; *indexPtr++ = base + 1;
|
|
||||||
*indexPtr++ = base; *indexPtr++ = base + 2;
|
|
||||||
}
|
}
|
||||||
// Adjust the final index to complete the circle
|
} else if (m_lightType == LightType::Point) {
|
||||||
*(--indexPtr) = 0;
|
createCircle(0, 0.f, 0, 1, 2);
|
||||||
} else if (qobject_cast<QQuick3DPointLight *>(m_light)) {
|
createCircle(segments, 0.f, 2, 0, 1);
|
||||||
const double innerRad = .3;
|
createCircle(segments * 2, 0.f, 1, 2, 0);
|
||||||
vertexSize = 0;
|
} else if (m_lightType == LightType::Spot) {
|
||||||
indexSize = 0;
|
createCircle(0, -1.f, 0, 1, 2);
|
||||||
int vertexIndex = 0;
|
|
||||||
for (quint16 i = 0; i < pointLightDensity; ++i) {
|
|
||||||
double latAngle = (((.9 / (pointLightDensity - 1)) * i) + .05) * M_PI;
|
|
||||||
quint16 longPoints = pointLightDensity * 2 * qSin(latAngle);
|
|
||||||
latAngle -= M_PI_2;
|
|
||||||
const double longSegment = M_PI * 2. / double(longPoints);
|
|
||||||
for (quint16 j = 0; j < longPoints; ++j) {
|
|
||||||
double longAngle = longSegment * j;
|
|
||||||
float q = float(qCos(latAngle));
|
|
||||||
float x = float(qCos(longAngle) * q);
|
|
||||||
float y = float(qSin(latAngle));
|
|
||||||
float z = float(qSin(longAngle) * q);
|
|
||||||
|
|
||||||
*dataPtr++ = x * innerRad; *dataPtr++ = y * innerRad; *dataPtr++ = z * innerRad;
|
|
||||||
*dataPtr++ = x; *dataPtr++ = y; *dataPtr++ = z;
|
|
||||||
*indexPtr++ = vertexIndex; *indexPtr++ = vertexIndex + 1;
|
|
||||||
|
|
||||||
vertexIndex += 2;
|
|
||||||
vertexSize += 6 * sizeof(float);
|
|
||||||
indexSize += 2 * sizeof(quint16);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
vertexData.resize(vertexSize);
|
|
||||||
indexData.resize(indexSize);
|
|
||||||
} else if (qobject_cast<QQuick3DSpotLight *>(m_light)) {
|
|
||||||
const quint16 segments = spotArc * spotCone;
|
|
||||||
const double segment = M_PI * 2. / double(segments);
|
|
||||||
|
|
||||||
// Circle
|
|
||||||
for (quint16 i = 0; i < segments; ++i) {
|
|
||||||
float x = float(qCos(i * segment));
|
|
||||||
float y = float(qSin(i * segment));
|
|
||||||
*dataPtr++ = x; *dataPtr++ = y; *dataPtr++ = -2.f;
|
|
||||||
*indexPtr++ = i; *indexPtr++ = i + 1;
|
|
||||||
}
|
|
||||||
// Adjust the final index to complete the circle
|
|
||||||
*(indexPtr - 1) = 0;
|
|
||||||
|
|
||||||
// Cone tip
|
// Cone tip
|
||||||
*dataPtr++ = 0.f; *dataPtr++ = 0.f; *dataPtr++ = 0.f;
|
*dataPtr++ = 0.f; *dataPtr++ = 0.f; *dataPtr++ = 0.f;
|
||||||
quint16 tipIndex = segments;
|
quint16 tipIndex = segments;
|
||||||
|
|
||||||
// Cone lines
|
// Cone lines
|
||||||
for (quint16 i = 0; i < spotCone; ++i) {
|
for (quint16 i = 0; i < dirLines; ++i) {
|
||||||
*indexPtr++ = tipIndex;
|
*indexPtr++ = tipIndex;
|
||||||
*indexPtr++ = i * spotArc;
|
*indexPtr++ = i * arc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -28,7 +28,6 @@
|
|||||||
#ifdef QUICK3D_MODULE
|
#ifdef QUICK3D_MODULE
|
||||||
|
|
||||||
#include <QtQuick3D/private/qquick3dgeometry_p.h>
|
#include <QtQuick3D/private/qquick3dgeometry_p.h>
|
||||||
#include <QtQuick3D/private/qquick3dabstractlight_p.h>
|
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -36,19 +35,28 @@ namespace Internal {
|
|||||||
class LightGeometry : public QQuick3DGeometry
|
class LightGeometry : public QQuick3DGeometry
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(QQuick3DAbstractLight *light READ light WRITE setLight NOTIFY lightChanged)
|
Q_PROPERTY(LightType lightType READ lightType WRITE setLightType NOTIFY lightTypeChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum class LightType {
|
||||||
|
Invalid,
|
||||||
|
Spot,
|
||||||
|
Area,
|
||||||
|
Directional,
|
||||||
|
Point
|
||||||
|
};
|
||||||
|
Q_ENUM(LightType)
|
||||||
|
|
||||||
LightGeometry();
|
LightGeometry();
|
||||||
~LightGeometry() override;
|
~LightGeometry() override;
|
||||||
|
|
||||||
QQuick3DAbstractLight *light() const;
|
LightType lightType() const;
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
void setLight(QQuick3DAbstractLight *light);
|
void setLightType(LightType lightType);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void lightChanged();
|
void lightTypeChanged();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QSSGRenderGraphObject *updateSpatialNode(QSSGRenderGraphObject *node) override;
|
QSSGRenderGraphObject *updateSpatialNode(QSSGRenderGraphObject *node) override;
|
||||||
@@ -56,7 +64,7 @@ protected:
|
|||||||
private:
|
private:
|
||||||
void fillVertexData(QByteArray &vertexData, QByteArray &indexData,
|
void fillVertexData(QByteArray &vertexData, QByteArray &indexData,
|
||||||
QVector3D &minBounds, QVector3D &maxBounds);
|
QVector3D &minBounds, QVector3D &maxBounds);
|
||||||
QQuick3DAbstractLight *m_light = nullptr;
|
LightType m_lightType = LightType::Invalid;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -16,7 +16,10 @@
|
|||||||
<file>mockfiles/CameraFrustum.qml</file>
|
<file>mockfiles/CameraFrustum.qml</file>
|
||||||
<file>mockfiles/CameraGizmo.qml</file>
|
<file>mockfiles/CameraGizmo.qml</file>
|
||||||
<file>mockfiles/LightModel.qml</file>
|
<file>mockfiles/LightModel.qml</file>
|
||||||
|
<file>mockfiles/LightIconGizmo.qml</file>
|
||||||
<file>mockfiles/LightGizmo.qml</file>
|
<file>mockfiles/LightGizmo.qml</file>
|
||||||
|
<file>mockfiles/SpotLightHandle.qml</file>
|
||||||
|
<file>mockfiles/AdjustableArrow.qml</file>
|
||||||
<file>mockfiles/IconGizmo.qml</file>
|
<file>mockfiles/IconGizmo.qml</file>
|
||||||
<file>mockfiles/Overlay2D.qml</file>
|
<file>mockfiles/Overlay2D.qml</file>
|
||||||
<file>mockfiles/HelperGrid.qml</file>
|
<file>mockfiles/HelperGrid.qml</file>
|
||||||
|
Reference in New Issue
Block a user