aboutsummaryrefslogtreecommitdiffstats
path: root/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/lightgeometry.cpp
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@qt.io>2020-05-04 17:42:22 +0300
committerMiikka Heikkinen <miikka.heikkinen@qt.io>2020-06-09 12:09:41 +0000
commita3e6e24427ddfb2254becbbc60025a0eac04735c (patch)
tree015c1e4866b562a39e007f45aa3bcd1821478fb1 /share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/lightgeometry.cpp
parent4d23e6300f2525f9cc1483d79d8abe7938cbdea2 (diff)
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>
Diffstat (limited to 'share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/lightgeometry.cpp')
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/lightgeometry.cpp157
1 files changed, 59 insertions, 98 deletions
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/lightgeometry.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/lightgeometry.cpp
index 6c2c2c28e7..7b9d898b17 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/lightgeometry.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/lightgeometry.cpp
@@ -29,10 +29,6 @@
#include <QtQuick3DRuntimeRender/private/qssgrendergeometry_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 <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;
- m_light = light;
+ m_lightType = lightType;
- emit lightChanged();
+ emit lightTypeChanged();
update();
}
QSSGRenderGraphObject *LightGeometry::updateSpatialNode(QSSGRenderGraphObject *node)
{
- if (!m_light)
+ if (m_lightType == LightType::Invalid)
return node;
node = QQuick3DGeometry::updateSpatialNode(node);
@@ -99,28 +95,26 @@ void LightGeometry::fillVertexData(QByteArray &vertexData, QByteArray &indexData
{
int vertexSize = 0;
int indexSize = 0;
- const int dirSegments = 12; // Segment lines in directional light circle
- const int spotArc = 6; // Segment lines per cone line in spotlight arc
- const int spotCone = 4; // Lines in spotlight cone
- const int pointLightDensity = 5;
-
- if (qobject_cast<QQuick3DAreaLight *>(m_light)) {
- // Area light model is a rectangle with perpendicular lines on corners
- vertexSize = int(sizeof(float)) * 3 * 8;
- indexSize = int(sizeof(quint16)) * 8 * 2;
- } else if (qobject_cast<QQuick3DDirectionalLight *>(m_light)) {
+ const int arc = 12; // Segment lines per cone line in spot/directional light arc
+ const int dirLines = 4; // Directional lines in spot/directional light
+ const quint16 segments = arc * dirLines;
+ const double segment = M_PI * 2. / double(segments);
+
+ if (m_lightType == LightType::Area) {
+ // Area light model is a rectangle
+ vertexSize = int(sizeof(float)) * 3 * 4;
+ indexSize = int(sizeof(quint16)) * 4 * 2;
+ } else if (m_lightType == LightType::Directional) {
// Directional light model is a circle with perpendicular lines on circumference vertices
- vertexSize = int(sizeof(float)) * 3 * dirSegments * 2;
- indexSize = int(sizeof(quint16)) * dirSegments * 2 * 2;
- } else if (qobject_cast<QQuick3DPointLight *>(m_light)) {
- // Point light model is a set of lines radiating from central point.
- // We reserve more than we need so we don't have to calculate the actual need here,
- // and resize later when we know the exact count.
- vertexSize = int(sizeof(float)) * 3 * pointLightDensity * pointLightDensity * 4;
- indexSize = int(sizeof(quint16)) * pointLightDensity * pointLightDensity * 4;
- } else if (qobject_cast<QQuick3DSpotLight *>(m_light)) {
- vertexSize = int(sizeof(float)) * 3 * (spotArc * spotCone + 1);
- indexSize = int(sizeof(quint16)) * (spotArc + 1) * spotCone * 2;
+ vertexSize = int(sizeof(float)) * 3 * (segments + dirLines);
+ indexSize = int(sizeof(quint16)) * (segments + dirLines) * 2;
+ } else if (m_lightType == LightType::Point) {
+ // Point light model is a set of three perpendicular circles
+ vertexSize = int(sizeof(float)) * 3 * segments * 3;
+ indexSize = int(sizeof(quint16)) * segments * 2 * 3;
+ } else if (m_lightType == LightType::Spot) {
+ vertexSize = int(sizeof(float)) * 3 * (segments + 1);
+ indexSize = int(sizeof(quint16)) * (segments + dirLines) * 2;
}
vertexData.resize(vertexSize);
indexData.resize(indexSize);
@@ -128,89 +122,56 @@ void LightGeometry::fillVertexData(QByteArray &vertexData, QByteArray &indexData
auto dataPtr = reinterpret_cast<float *>(vertexData.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++ = -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++ = 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;
- } else if (qobject_cast<QQuick3DDirectionalLight *>(m_light)) {
- const double segment = M_PI * 2. / double(dirSegments);
- 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
- *(--indexPtr) = 0;
- } else if (qobject_cast<QQuick3DPointLight *>(m_light)) {
- const double innerRad = .3;
- vertexSize = 0;
- indexSize = 0;
- 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);
- }
+ } else if (m_lightType == LightType::Directional) {
+ createCircle(0, 0.f, 0, 1, 2);
+
+ // Dir lines
+ for (quint16 i = 0; i < dirLines; ++i) {
+ auto circlePtr = reinterpret_cast<float *>(vertexData.data()) + (3 * arc * i);
+ *dataPtr++ = *circlePtr; *dataPtr++ = *(circlePtr + 1); *dataPtr++ = -3.f;
+ *indexPtr++ = i * arc;
+ *indexPtr++ = i + segments;
}
- 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;
+ } else if (m_lightType == LightType::Point) {
+ createCircle(0, 0.f, 0, 1, 2);
+ createCircle(segments, 0.f, 2, 0, 1);
+ createCircle(segments * 2, 0.f, 1, 2, 0);
+ } else if (m_lightType == LightType::Spot) {
+ createCircle(0, -1.f, 0, 1, 2);
// Cone tip
*dataPtr++ = 0.f; *dataPtr++ = 0.f; *dataPtr++ = 0.f;
quint16 tipIndex = segments;
// Cone lines
- for (quint16 i = 0; i < spotCone; ++i) {
+ for (quint16 i = 0; i < dirLines; ++i) {
*indexPtr++ = tipIndex;
- *indexPtr++ = i * spotArc;
+ *indexPtr++ = i * arc;
}
}