diff options
| author | Tarja Sundqvist <tarja.sundqvist@qt.io> | 2025-10-11 00:05:07 +0300 |
|---|---|---|
| committer | Tarja Sundqvist <tarja.sundqvist@qt.io> | 2025-10-11 00:05:07 +0300 |
| commit | 889447b1f96230f9043422a8ad1a6202854235d8 (patch) | |
| tree | f29d10b4544a96dde54a8c8701408592199039d7 | |
| parent | 730898b245931c55ff61ec3a892d600dfa37e175 (diff) | |
| parent | 6a96e2c9788093acedf21cd023c2db29197e50fc (diff) | |
Merge tag 'v6.5.7-lts' into tqtc/lts-6.5-opensourcev6.5.7-lts-lgpl6.5
Qt 6.5.7-lts release
Conflicts solved:
dependencies.yaml
Change-Id: I0534380166c74e4975788b4ec4b5b5a238c0984d
32 files changed, 802 insertions, 153 deletions
diff --git a/.cmake.conf b/.cmake.conf index 647dec24..0435c0f3 100644 --- a/.cmake.conf +++ b/.cmake.conf @@ -1,3 +1,3 @@ -set(QT_REPO_MODULE_VERSION "6.5.6") +set(QT_REPO_MODULE_VERSION "6.5.7") set(QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT "alpha1") list(APPEND QT_EXTRA_INTERNAL_TARGET_DEFINES "QT_NO_AS_CONST=1") diff --git a/dependencies.yaml b/dependencies.yaml index 70f269fd..e11d4e35 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -1,13 +1,13 @@ dependencies: ../tqtc-qtbase: - ref: 5d8e9a8415562ba004b38508d91e1fa0254c17d3 + ref: fc0e66eefe3a08428ca4a6e92c66f37ac126d3c4 required: true ../tqtc-qtdeclarative: - ref: ff0a47c8f267e905113b82c53af2742027f0eca6 + ref: 844f9b9b376838bcb44324984876f8bf99d85d38 required: true ../tqtc-qtquicktimeline: - ref: 8d8c195e7206974608b1eedcc79c51b41eb34a1c + ref: 7190a3e4664062401263ecad62b2c33ca00f60cf required: false ../tqtc-qtshadertools: - ref: ac330781f44d174045e7a6770ed81c1dd29691f8 + ref: 4c6749e750764297ee4237d9a1f2657b8313c4f7 required: true diff --git a/examples/quick3d/hellocube/main.qml b/examples/quick3d/hellocube/main.qml index a020a65b..ae1da5f8 100644 --- a/examples/quick3d/hellocube/main.qml +++ b/examples/quick3d/hellocube/main.qml @@ -133,7 +133,11 @@ Window { } onClicked: { - if (clickme.state == "flipped") { + // do nothing while animating + if (flip1.running || flip2.running) + return; + + if (clickme.state === "flipped") { clickme.state = ""; flip2.start(); } else { diff --git a/examples/quick3d/lights/main.qml b/examples/quick3d/lights/main.qml index 3cf129a0..f79eb0ec 100644 --- a/examples/quick3d/lights/main.qml +++ b/examples/quick3d/lights/main.qml @@ -113,8 +113,8 @@ Window { scale: Qt.vector3d(15, 15, 15) eulerRotation.x: -90 materials: [ - DefaultMaterial { - diffuseColor: Qt.rgba(0.8, 0.6, 0.4, 1.0) + PrincipledMaterial { + baseColor: Qt.rgba(0.8, 0.6, 0.4, 1.0) } ] } @@ -123,8 +123,8 @@ Window { z: -400 scale: Qt.vector3d(15, 15, 15) materials: [ - DefaultMaterial { - diffuseColor: Qt.rgba(0.8, 0.8, 0.9, 1.0) + PrincipledMaterial { + baseColor: Qt.rgba(0.8, 0.8, 0.9, 1.0) } ] } @@ -132,8 +132,8 @@ Window { RotatingTeaPot { visible: !checkBoxCustomMaterial.checked - material: DefaultMaterial { - diffuseColor: Qt.rgba(0.9, 0.9, 0.9, 1.0) + material: PrincipledMaterial { + baseColor: Qt.rgba(0.9, 0.9, 0.9, 1.0) } animate: checkBoxAnimate.checked } diff --git a/src/3rdparty/tinyexr/qt_attribution.json b/src/3rdparty/tinyexr/qt_attribution.json index a6c08f5d..aca61c02 100644 --- a/src/3rdparty/tinyexr/qt_attribution.json +++ b/src/3rdparty/tinyexr/qt_attribution.json @@ -7,8 +7,8 @@ "SecurityCritical": true, "Homepage": "https://github.com/syoyo/tinyexr", - "Version": "v1.0.8", - "DownloadLocation": "https://github.com/syoyo/tinyexr/releases/tag/v1.0.8", + "Version": "v1.0.9", + "DownloadLocation": "https://github.com/syoyo/tinyexr/releases/tag/v1.0.9", "License": "BSD 3-clause \"New\" or \"Revised\" License", "LicenseId": "BSD-3-Clause", diff --git a/src/3rdparty/tinyexr/tinyexr.h b/src/3rdparty/tinyexr/tinyexr.h index d4001575..537e1984 100644 --- a/src/3rdparty/tinyexr/tinyexr.h +++ b/src/3rdparty/tinyexr/tinyexr.h @@ -9287,9 +9287,6 @@ int SaveEXR(const float *data, int width, int height, int components, } int ret = SaveEXRImageToFile(&image, &header, outfilename, err); - if (ret != TINYEXR_SUCCESS) { - return ret; - } free(header.channels); free(header.pixel_types); diff --git a/src/assetutils/qquick3druntimeloader.cpp b/src/assetutils/qquick3druntimeloader.cpp index ed332802..04cd638f 100644 --- a/src/assetutils/qquick3druntimeloader.cpp +++ b/src/assetutils/qquick3druntimeloader.cpp @@ -176,26 +176,26 @@ void QQuick3DRuntimeLoader::loadSource() break; } - emit statusChanged(); - emit errorStringChanged(); - - if (m_status != Status::Success) { + if (m_status == Status::Success) { + // We create a dummy root node here, as it will be the parent to the first-level nodes + // and resources. If we use 'this' those first-level nodes/resources won't be deleted + // when a new scene is loaded. + m_root = new QQuick3DNode(this); + m_imported = QSSGRuntimeUtils::createScene(*m_root, scene); + m_assetId = scene.id; + m_boundsDirty = true; + m_instancingChanged = m_instancing != nullptr; + updateModels(); + // Cleanup scene before deleting. + scene.cleanup(); + } else { m_source.clear(); emit sourceChanged(); - return; } - // We create a dummy root node here, as it will be the parent to the first-level nodes - // and resources. If we use 'this' those first-level nodes/resources won't be deleted - // when a new scene is loaded. - m_root = new QQuick3DNode(this); - m_imported = QSSGRuntimeUtils::createScene(*m_root, scene); - m_assetId = scene.id; - m_boundsDirty = true; - m_instancingChanged = m_instancing != nullptr; - updateModels(); - // Cleanup scene before deleting. - scene.cleanup(); + emit statusChanged(); + emit errorStringChanged(); + } void QQuick3DRuntimeLoader::updateModels() diff --git a/src/helpers/randominstancing.cpp b/src/helpers/randominstancing.cpp index 37cb3b41..d63c8d9f 100644 --- a/src/helpers/randominstancing.cpp +++ b/src/helpers/randominstancing.cpp @@ -192,6 +192,7 @@ void QQuick3DRandomInstancing::setInstanceCount(int instanceCount) if (instanceCount == m_randomCount) return; m_randomCount = instanceCount; + emit instanceCountChanged(); m_dirty = true; markDirty(); } diff --git a/src/quick3d/qquick3dinstancing.cpp b/src/quick3d/qquick3dinstancing.cpp index ee63e54b..6046f5a2 100644 --- a/src/quick3d/qquick3dinstancing.cpp +++ b/src/quick3d/qquick3dinstancing.cpp @@ -689,7 +689,7 @@ void QQuick3DInstanceListEntry::setRotation(QQuaternion rotation) } /*! - \qmlproperty vector3d QtQuick3D::InstanceListEntry::color + \qmlproperty color QtQuick3D::InstanceListEntry::color This property specifies the color for the instance. */ diff --git a/src/quick3d/qquick3dloader.cpp b/src/quick3d/qquick3dloader.cpp index c1a1ea19..49e9de3f 100644 --- a/src/quick3d/qquick3dloader.cpp +++ b/src/quick3d/qquick3dloader.cpp @@ -61,12 +61,9 @@ QQuick3DLoader::QQuick3DLoader(QQuick3DNode *parent) QQuick3DLoader::~QQuick3DLoader() { - delete m_itemContext; - m_itemContext = nullptr; + clear(); delete m_incubator; m_incubator = nullptr; - disposeInitialPropertyValues(); - clear(); } /*! diff --git a/src/quick3d/qquick3dmodel.cpp b/src/quick3d/qquick3dmodel.cpp index 597bb62d..53b455fc 100644 --- a/src/quick3d/qquick3dmodel.cpp +++ b/src/quick3d/qquick3dmodel.cpp @@ -1033,7 +1033,7 @@ void QQuick3DModel::qmlClearMaterials(QQmlListProperty<QQuick3DMaterial> *list) mat.refed = false; } } - mat.material->disconnect(self, SLOT(onMaterialDestroyed(QObject*))); + disconnect(mat.material, &QQuick3DMaterial::destroyed, self, &QQuick3DModel::onMaterialDestroyed); } self->m_materials.clear(); self->markDirty(QQuick3DModel::MaterialsDirty); @@ -1110,7 +1110,7 @@ void QQuick3DModel::qmlClearMorphTargets(QQmlListProperty<QQuick3DMorphTarget> * for (const auto &morph : std::as_const(self->m_morphTargets)) { if (morph->parentItem() == nullptr) QQuick3DObjectPrivate::get(morph)->derefSceneManager(); - morph->disconnect(self, SLOT(onMorphTargetDestroyed(QObject*))); + disconnect(morph, &QQuick3DMorphTarget::destroyed, self, &QQuick3DModel::onMorphTargetDestroyed); } self->m_morphTargets.clear(); self->m_numMorphAttribs = 0; diff --git a/src/quick3d/qquick3dresourceloader.cpp b/src/quick3d/qquick3dresourceloader.cpp index f508ae73..ddeb8a02 100644 --- a/src/quick3d/qquick3dresourceloader.cpp +++ b/src/quick3d/qquick3dresourceloader.cpp @@ -236,7 +236,7 @@ void QQuick3DResourceLoader::qmlClearGeometries(QQmlListProperty<QQuick3DGeometr for (const auto &geometry : std::as_const(self->m_geometries)) { if (geometry->parentItem() == nullptr) QQuick3DObjectPrivate::get(geometry)->derefSceneManager(); - geometry->disconnect(self, SLOT(onMorphTargetDestroyed(QObject*))); + disconnect(geometry, &QQuick3DGeometry::destroyed, self, &QQuick3DResourceLoader::onGeometryDestroyed); } self->m_geometries.clear(); @@ -292,7 +292,7 @@ void QQuick3DResourceLoader::qmlClearTextures(QQmlListProperty<QQuick3DTexture> for (const auto &data : std::as_const(self->m_textures)) { if (data->parentItem() == nullptr) QQuick3DObjectPrivate::get(data)->derefSceneManager(); - data->disconnect(self, SLOT(onMorphTargetDestroyed(QObject*))); + disconnect(data, &QQuick3DTextureData::destroyed, self, &QQuick3DResourceLoader::onTextureDestroyed); } self->m_textures.clear(); self->markDirty(QQuick3DResourceLoader::TexturesDirty); diff --git a/src/quick3d/qquick3dskin.cpp b/src/quick3d/qquick3dskin.cpp index e5f0568b..688a847f 100644 --- a/src/quick3d/qquick3dskin.cpp +++ b/src/quick3d/qquick3dskin.cpp @@ -145,9 +145,9 @@ qsizetype QQuick3DSkin::qmlJointsCount(QQmlListProperty<QQuick3DNode> *list) void QQuick3DSkin::qmlClearJoints(QQmlListProperty<QQuick3DNode> *list) { QQuick3DSkin *self = static_cast<QQuick3DSkin *>(list->object); - for (const auto &joint : std::as_const(self->m_joints)) { - joint->disconnect(self, SLOT(onJointDestroyed(QObject*))); - } + for (const auto &joint : std::as_const(self->m_joints)) + disconnect(joint, &QQuick3DNode::destroyed, self, &QQuick3DSkin::onJointDestroyed); + self->m_joints.clear(); self->m_boneData.clear(); self->markDirty(); diff --git a/src/quick3d/qquick3dtexture.cpp b/src/quick3d/qquick3dtexture.cpp index fb6427cd..1372da8b 100644 --- a/src/quick3d/qquick3dtexture.cpp +++ b/src/quick3d/qquick3dtexture.cpp @@ -8,6 +8,7 @@ #include <QtQml/QQmlFile> #include <QtQuick/QQuickItem> #include <QtQuick/private/qquickitem_p.h> +#include <QSGTextureProvider> #include <QtCore/qmath.h> #include "qquick3dobject_p.h" diff --git a/src/quick3dparticles/qquick3dparticlemodelblendparticle.cpp b/src/quick3dparticles/qquick3dparticlemodelblendparticle.cpp index 1e2eb2f4..911a42f7 100644 --- a/src/quick3dparticles/qquick3dparticlemodelblendparticle.cpp +++ b/src/quick3dparticles/qquick3dparticlemodelblendparticle.cpp @@ -568,9 +568,11 @@ QSSGRenderGraphObject *QQuick3DParticleModelBlendParticle::updateSpatialNode(QSS Q_QUICK3D_PROFILE_ASSIGN_ID_SG(this, spatialNode); } #if QT_CONFIG(qml_debug) - auto *geometrySpatialNode = QQuick3DObjectPrivate::get(m_modelGeometry)->spatialNode; - if (geometrySpatialNode) - Q_QUICK3D_PROFILE_ASSIGN_ID_SG(this, geometrySpatialNode); + if (m_modelGeometry) { + auto *geometrySpatialNode = QQuick3DObjectPrivate::get(m_modelGeometry)->spatialNode; + if (geometrySpatialNode) + Q_QUICK3D_PROFILE_ASSIGN_ID_SG(this, geometrySpatialNode); + } #endif QSSGRenderModel *model = static_cast<QSSGRenderModel *>(spatialNode); diff --git a/src/quick3dparticles/qquick3dparticlespriteparticle.cpp b/src/quick3dparticles/qquick3dparticlespriteparticle.cpp index 4a743977..e66b5903 100644 --- a/src/quick3dparticles/qquick3dparticlespriteparticle.cpp +++ b/src/quick3dparticles/qquick3dparticlespriteparticle.cpp @@ -766,7 +766,7 @@ void QQuick3DParticleSpriteParticle::qmlClearLights(QQmlListProperty<QQuick3DAbs for (const auto &light : std::as_const(self->m_lights)) { if (light->parentItem() == nullptr) QQuick3DObjectPrivate::get(light)->derefSceneManager(); - light->disconnect(self, SLOT(onLightDestroyed(QObject*))); + disconnect(light, &QQuick3DParticleSpriteParticle::destroyed, self, &QQuick3DParticleSpriteParticle::onLightDestroyed); } self->m_lights.clear(); self->updateFeatureLevel(); diff --git a/src/runtimerender/graphobjects/qssgrendergraphobject_p.h b/src/runtimerender/graphobjects/qssgrendergraphobject_p.h index 3a163fa8..6ebfc1b7 100644 --- a/src/runtimerender/graphobjects/qssgrendergraphobject_p.h +++ b/src/runtimerender/graphobjects/qssgrendergraphobject_p.h @@ -126,6 +126,7 @@ struct Q_QUICK3DRUNTIMERENDER_EXPORT QSSGRenderGraphObject || (isTexture(type)) || (type == Type::Geometry) || (type == Type::TextureData) + || (type == Type::ModelInstance) || (type == Type::ResourceLoader)); } diff --git a/src/runtimerender/qssgrenderdefaultmaterialshadergenerator.cpp b/src/runtimerender/qssgrenderdefaultmaterialshadergenerator.cpp index 380f25ce..8e612584 100644 --- a/src/runtimerender/qssgrenderdefaultmaterialshadergenerator.cpp +++ b/src/runtimerender/qssgrenderdefaultmaterialshadergenerator.cpp @@ -362,11 +362,13 @@ static void generateShadowMapOcclusion(QSSGStageGeneratorBase &fragmentShader, fragmentShader.addUniform(names.shadowControlStem, "vec4"); fragmentShader.addUniform(names.shadowMatrixStem, "mat4"); + fragmentShader << " if (" << names.shadowControlStem << ".y > 0.01) {\n"; if (inType != QSSGRenderLight::Type::DirectionalLight) { - fragmentShader << " qt_shadow_map_occl = qt_sampleCubemap(" << names.shadowCubeStem << ", " << names.shadowControlStem << ", " << names.shadowMatrixStem << ", " << lightVarNames.lightPos << ".xyz, qt_varWorldPos, vec2(1.0, " << names.shadowControlStem << ".z));\n"; + fragmentShader << " qt_shadow_map_occl = qt_sampleCubemap(" << names.shadowCubeStem << ", " << names.shadowControlStem << ", " << names.shadowMatrixStem << ", " << lightVarNames.lightPos << ".xyz, qt_varWorldPos, vec2(1.0, " << names.shadowControlStem << ".z));\n"; } else { - fragmentShader << " qt_shadow_map_occl = qt_sampleOrthographic(" << names.shadowMapStem << ", " << names.shadowControlStem << ", " << names.shadowMatrixStem << ", qt_varWorldPos, vec2(1.0, " << names.shadowControlStem << ".z));\n"; + fragmentShader << " qt_shadow_map_occl = qt_sampleOrthographic(" << names.shadowMapStem << ", " << names.shadowControlStem << ", " << names.shadowMatrixStem << ", qt_varWorldPos, vec2(1.0, " << names.shadowControlStem << ".z));\n"; } + fragmentShader << " }\n"; } else { fragmentShader << " qt_shadow_map_occl = 1.0;\n"; } diff --git a/src/runtimerender/qssgrhicontext.cpp b/src/runtimerender/qssgrhicontext.cpp index 03ac1a28..09f4adc4 100644 --- a/src/runtimerender/qssgrhicontext.cpp +++ b/src/runtimerender/qssgrhicontext.cpp @@ -962,6 +962,12 @@ QRhiShaderResourceBindings *QSSGRhiContext::srb(const QSSGRhiShaderResourceBindi return srb; } +void QSSGRhiContext::releaseCachedSrb(QSSGRhiShaderResourceBindingList &bindings) +{ + auto srb = m_srbCache.take(bindings); + delete srb; +} + void QSSGRhiContext::releaseDrawCallData(QSSGRhiDrawCallData &dcd) { delete dcd.ubuf; @@ -1281,4 +1287,13 @@ void QSSGRhiContextStats::printRenderPass(const QSSGRhiContextStats::RenderPassI } } +void QSSGRhiContext::releaseInstanceBuffer(QSSGRenderInstanceTable *instanceTable) +{ + auto it = m_instanceBuffers.constFind(instanceTable); + if (it != m_instanceBuffers.constEnd()) { + it->buffer->destroy(); + m_instanceBuffers.erase(it); + } +} + QT_END_NAMESPACE diff --git a/src/runtimerender/qssgrhicontext_p.h b/src/runtimerender/qssgrhicontext_p.h index 4aaee51a..f4e4104e 100644 --- a/src/runtimerender/qssgrhicontext_p.h +++ b/src/runtimerender/qssgrhicontext_p.h @@ -951,6 +951,7 @@ public: QRhiShaderResourceBindings *srb(const QSSGRhiShaderResourceBindingList &bindings); void releaseDrawCallData(QSSGRhiDrawCallData &dcd); + void releaseCachedSrb(QSSGRhiShaderResourceBindingList &bindings); QRhiGraphicsPipeline *pipeline(const QSSGGraphicsPipelineStateKey &key, QRhiRenderPassDescriptor *rpDesc, QRhiShaderResourceBindings *srb); @@ -1000,6 +1001,8 @@ public: return m_instanceBuffersLod[model]; } + void releaseInstanceBuffer(QSSGRenderInstanceTable *instanceTable); + QSSGRhiParticleData &particleData(const QSSGRenderGraphObject *particlesOrModel) { return m_particleData[particlesOrModel]; diff --git a/src/runtimerender/qssgrhicustommaterialsystem.cpp b/src/runtimerender/qssgrhicustommaterialsystem.cpp index 2e873f80..cb372ec4 100644 --- a/src/runtimerender/qssgrhicustommaterialsystem.cpp +++ b/src/runtimerender/qssgrhicustommaterialsystem.cpp @@ -468,6 +468,7 @@ void QSSGCustomMaterialSystem::rhiPrepareRenderable(QSSGRhiGraphicsPipelineState bool srbChanged = false; if (!srb || bindings != dcd.bindings) { srb = rhiCtx->srb(bindings); + rhiCtx->releaseCachedSrb(dcd.bindings); dcd.bindings = bindings; srbChanged = true; } diff --git a/src/runtimerender/qssgrhiparticles.cpp b/src/runtimerender/qssgrhiparticles.cpp index f84b00ba..f121f35e 100644 --- a/src/runtimerender/qssgrhiparticles.cpp +++ b/src/runtimerender/qssgrhiparticles.cpp @@ -490,6 +490,7 @@ void QSSGParticleRenderer::rhiPrepareRenderable(QSSGRhiShaderPipeline &shaderPip bool srbChanged = false; if (!srb || bindings != dcd.bindings) { srb = rhiCtx->srb(bindings); + rhiCtx->releaseCachedSrb(dcd.bindings); dcd.bindings = bindings; srbChanged = true; } diff --git a/src/runtimerender/rendererimpl/qssgrenderer.cpp b/src/runtimerender/rendererimpl/qssgrenderer.cpp index 951a6609..6e1d1358 100644 --- a/src/runtimerender/rendererimpl/qssgrenderer.cpp +++ b/src/runtimerender/rendererimpl/qssgrenderer.cpp @@ -202,9 +202,13 @@ static void cleanupResourcesImpl(const QSSGRenderContextInterface &rci, const Co } else if (resource->type == QSSGRenderGraphObject::Type::Model) { auto model = static_cast<QSSGRenderModel*>(resource); rhi->cleanupDrawCallData(model); + delete model->particleBuffer; } else if (resource->type == QSSGRenderGraphObject::Type::TextureData) { auto textureData = static_cast<QSSGRenderTextureData *>(resource); bufferManager->releaseTextureData(textureData); + } else if (resource->type == QSSGRenderGraphObject::Type::ModelInstance) { + auto *table = static_cast<QSSGRenderInstanceTable *>(resource); + rhi->releaseInstanceBuffer(table); } // ### There might be more types that need to be supported @@ -853,7 +857,7 @@ static void setupCameraForShadowMap(const QSSGRenderCamera &inCamera, theCamera.clipFar = 0.5f * finalDims.z(); theCamera.localTransform = QSSGRenderNode::calculateTransformMatrix(center, QSSGRenderNode::initScale, inLightPivot, QQuaternion::fromDirection(forward, up)); } else if (inLight->type == QSSGRenderLight::Type::PointLight) { - theCamera.lookAt(inLightPos, QVector3D(0, 1.0, 0), QVector3D(0, 0, 0), inLightPivot); + theCamera.lookAt(inLightPos, QVector3D(0, 1.0, 0), QVector3D(0, 0, 0), QVector3D(0, 0, 0)); } theCamera.calculateGlobalVariables(theViewport); @@ -971,14 +975,14 @@ static void setupCubeShadowCameras(const QSSGRenderLight *inLight, QSSGRenderCam }; const QVector3D inLightPos = inLight->getGlobalPos(); - const QVector3D inLightPivot = inLight->pivot; + const QVector3D lightPivot = QVector3D(0, 0, 0); for (int i = 0; i < 6; ++i) { inCameras[i].parent = nullptr; inCameras[i].clipNear = 1.0f; inCameras[i].clipFar = qMax<float>(2.0f, inLight->m_shadowMapFar); inCameras[i].fov = qDegreesToRadians(90.f); - inCameras[i].localTransform = QSSGRenderNode::calculateTransformMatrix(inLightPos, QSSGRenderNode::initScale, inLightPivot, rotOfs[i]); + inCameras[i].localTransform = QSSGRenderNode::calculateTransformMatrix(inLightPos, QSSGRenderNode::initScale, lightPivot, rotOfs[i]); inCameras[i].calculateGlobalVariables(theViewport); } @@ -1449,6 +1453,7 @@ void RenderHelpers::rhiPrepareRenderable(QSSGRhiContext *rhiCtx, bool srbChanged = false; if (!srb || bindings != dcd.bindings) { srb = rhiCtx->srb(bindings); + rhiCtx->releaseCachedSrb(dcd.bindings); dcd.bindings = bindings; srbChanged = true; } diff --git a/src/runtimerender/rendererimpl/qssgvertexpipelineimpl.cpp b/src/runtimerender/rendererimpl/qssgvertexpipelineimpl.cpp index 830aca17..20add5d6 100644 --- a/src/runtimerender/rendererimpl/qssgvertexpipelineimpl.cpp +++ b/src/runtimerender/rendererimpl/qssgvertexpipelineimpl.cpp @@ -181,7 +181,6 @@ void QSSGMaterialVertexPipeline::beginVertexGeneration(const QSSGShaderDefaultMa if (materialAdapter->usesCustomSkinning()) { vertexShader.addInclude("skinanim.glsllib"); vertexShader.addUniform("qt_boneTexture", "sampler2D"); - m_hasSkinning = false; } if (!materialAdapter->isUnshaded()) { @@ -310,7 +309,8 @@ void QSSGMaterialVertexPipeline::beginVertexGeneration(const QSSGShaderDefaultMa if (m_hasMorphing && !hasCustomVertexShader) vertexShader.append(" qt_vertPosition.xyz = qt_getMorphPosition(qt_vertPosition.xyz);"); - if (m_hasSkinning) { + m_needsSkinning = m_hasSkinning && !materialAdapter->usesCustomSkinning(); + if (m_needsSkinning) { vertexShader.append(" mat4 skinMat = mat4(1);"); vertexShader.append(" if (qt_vertWeights != vec4(0.0)) {"); vertexShader.append(" skinMat = qt_getSkinMatrix(qt_vertJoints, qt_vertWeights);"); @@ -400,7 +400,7 @@ void QSSGMaterialVertexPipeline::doGenerateVarTangent(const QSSGShaderDefaultMat { if (m_hasMorphing) vertex() << " qt_vertTangent = qt_getMorphTangent(qt_vertTangent);\n"; - if (m_hasSkinning) { + if (m_needsSkinning) { vertex() << " if (qt_vertWeights != vec4(0.0))\n" << " qt_vertTangent = (skinMat * vec4(qt_vertTangent, 0.0)).xyz;\n"; @@ -420,7 +420,7 @@ void QSSGMaterialVertexPipeline::doGenerateVarBinormal(const QSSGShaderDefaultMa { if (m_hasMorphing) vertex() << " qt_vertBinormal = qt_getMorphBinormal(qt_vertBinormal);\n"; - if (m_hasSkinning) { + if (m_needsSkinning) { vertex() << " if (qt_vertWeights != vec4(0.0))\n" << " qt_vertBinormal = (skinMat * vec4(qt_vertBinormal, 0.0)).xyz;\n"; } diff --git a/src/runtimerender/rendererimpl/qssgvertexpipelineimpl_p.h b/src/runtimerender/rendererimpl/qssgvertexpipelineimpl_p.h index 3fea10a2..d9dfe3e2 100644 --- a/src/runtimerender/rendererimpl/qssgvertexpipelineimpl_p.h +++ b/src/runtimerender/rendererimpl/qssgvertexpipelineimpl_p.h @@ -49,6 +49,7 @@ struct QSSGMaterialVertexPipeline GenerationFlags m_generationFlags; bool m_hasSkinning; + bool m_needsSkinning; bool m_hasMorphing; TStrTableStrMap m_interpolationParameters; QList<QByteArray> m_addedFunctions; diff --git a/src/runtimerender/resourcemanager/qssgrenderbuffermanager.cpp b/src/runtimerender/resourcemanager/qssgrenderbuffermanager.cpp index 721ba570..8d2fe95b 100644 --- a/src/runtimerender/resourcemanager/qssgrenderbuffermanager.cpp +++ b/src/runtimerender/resourcemanager/qssgrenderbuffermanager.cpp @@ -207,7 +207,7 @@ QSSGRenderImageTexture QSSGBufferManager::loadRenderImage(const QSSGRenderImage CreateRhiTextureFlags rhiTexFlags = ScanForTransparency; if (image->type == QSSGRenderGraphObject::Type::ImageCube) rhiTexFlags |= CubeMap; - if (!createRhiTexture(foundIt.value().renderImageTexture, theLoadedTexture.data(), inMipMode, rhiTexFlags, QFileInfo(path).fileName())) { + if (!setRhiTexture(foundIt.value().renderImageTexture, theLoadedTexture.data(), inMipMode, rhiTexFlags, QFileInfo(path).fileName())) { foundIt.value() = ImageData(); } else { #ifdef QSSG_RENDERBUFFER_DEBUGGING @@ -237,10 +237,15 @@ QSSGRenderImageTexture QSSGBufferManager::loadTextureData(QSSGRenderTextureData if (theImageData == customTextureMap.end()) { theImageData = customTextureMap.insert(imageKey, ImageData()); } else if (data->generationId() != theImageData->generationId) { - // release first - releaseTextureData(imageKey); - // reinsert the placeholder since releaseTextureData removed from map - theImageData = customTextureMap.insert(imageKey, ImageData()); + auto &renderImageTexture = theImageData.value().renderImageTexture; + if (toRhiFormat(data->format()) != renderImageTexture.m_texture->format() + || data->size() != renderImageTexture.m_texture->pixelSize()) { + // release first + releaseTextureData(imageKey); + // reinsert the placeholder since releaseTextureData removed from map + theImageData = customTextureMap.insert(imageKey, ImageData()); + } + theImageData->generationId = data->generationId(); } else { // Return the currently loaded texture theImageData.value().usageCounts[currentLayer]++; @@ -252,12 +257,14 @@ QSSGRenderImageTexture QSSGBufferManager::loadTextureData(QSSGRenderTextureData if (!data->textureData().isNull()) { theLoadedTexture.reset(QSSGLoadedTexture::loadTextureData(data)); theLoadedTexture->ownsData = false; - if (createRhiTexture(theImageData.value().renderImageTexture, theLoadedTexture.data(), inMipMode, {}, data->debugObjectName)) { -#ifdef QSSG_RENDERBUFFER_DEBUGGING - qDebug() << "+ uploadTexture: " << data << currentLayer; -#endif - theImageData.value().generationId = data->generationId(); - increaseMemoryStat(theImageData.value().renderImageTexture.m_texture); + + bool wasTextureCreated = false; + + if (setRhiTexture(theImageData.value().renderImageTexture, theLoadedTexture.data(), inMipMode, {}, data->debugObjectName, &wasTextureCreated)) { + if (wasTextureCreated) { + theImageData.value().generationId = data->generationId(); + increaseMemoryStat(theImageData.value().renderImageTexture.m_texture); + } } else { theImageData.value() = ImageData(); } @@ -286,7 +293,7 @@ QSSGRenderImageTexture QSSGBufferManager::loadLightmap(const QSSGRenderModel &mo qCWarning(WARNING, "Failed to load lightmap image: %s", qPrintable(imagePath)); foundIt = imageMap.insert(imageKey, ImageData()); if (theLoadedTexture) { - if (!createRhiTexture(foundIt.value().renderImageTexture, theLoadedTexture.data(), MipModeDisable, {}, imagePath)) + if (!setRhiTexture(foundIt.value().renderImageTexture, theLoadedTexture.data(), MipModeDisable, {}, imagePath)) foundIt.value() = ImageData(); result = foundIt.value().renderImageTexture; } @@ -887,111 +894,134 @@ bool QSSGBufferManager::createEnvironmentMap(const QSSGLoadedTexture *inImage, Q return true; } -bool QSSGBufferManager::createRhiTexture(QSSGRenderImageTexture &texture, - const QSSGLoadedTexture *inTexture, - MipMode inMipMode, - CreateRhiTextureFlags inFlags, - const QString &debugObjectName) +bool QSSGBufferManager::setRhiTexture(QSSGRenderImageTexture &texture, + const QSSGLoadedTexture *inTexture, + MipMode inMipMode, + CreateRhiTextureFlags inFlags, + const QString &debugObjectName, + bool *wasTextureCreated) { Q_ASSERT(inMipMode != MipModeFollowRenderImage); QVarLengthArray<QRhiTextureUploadEntry, 16> textureUploads; int textureSampleCount = 1; QRhiTexture::Flags textureFlags; - int mipmapCount = 1; const bool checkTransp = inFlags.testFlag(ScanForTransparency); bool hasTransp = false; const auto &context = m_contextInterface->rhiContext(); auto *rhi = context->rhi(); - QRhiTexture::Format rhiFormat = QRhiTexture::UnknownFormat; - QSize size; - if (inTexture->format.format == QSSGRenderTextureFormat::Format::RGBE8) - texture.m_flags.setRgbe8(true); - if (inMipMode == MipModeBsdf && (inTexture->data || inTexture->textureFileData.isValid())) { - // Before creating an environment map, check if the provided texture is a - // pre-baked environment map - if (inTexture->textureFileData.isValid() && inTexture->textureFileData.keyValueMetadata().contains("QT_IBL_BAKER_VERSION")) { - Q_ASSERT(inTexture->textureFileData.numFaces() == 6); - Q_ASSERT(inTexture->textureFileData.numLevels() >= 5); - - const QTextureFileData &tex = inTexture->textureFileData; - rhiFormat = toRhiFormat(inTexture->format.format); - size = tex.size(); - mipmapCount = tex.numLevels(); - const int faceCount = tex.numFaces(); - QRhiTexture *environmentCubeMap = rhi->newTexture(rhiFormat, size, 1, QRhiTexture::CubeMap | QRhiTexture::MipMapped); - environmentCubeMap->setName(debugObjectName.toLatin1()); - environmentCubeMap->create(); + + QRhiTexture::Format rhiFormat = toRhiFormat(inTexture->format.format); + const QTextureFileData &texFileData = inTexture->textureFileData; + QSize size = texFileData.isValid() ? texFileData.size() : QSize(inTexture->width, inTexture->height); + int mipmapCount = texFileData.isValid() ? texFileData.numLevels() : 1; + bool generateMipmaps = false; + + if (wasTextureCreated) + *wasTextureCreated = false; + + if (texture.m_texture == nullptr) { + if (inTexture->format.format == QSSGRenderTextureFormat::Format::RGBE8) + texture.m_flags.setRgbe8(true); + if (inMipMode == MipModeBsdf && (inTexture->data || texFileData.isValid())) { + // Before creating an environment map, check if the provided texture is a + // pre-baked environment map + if (texFileData.isValid() && texFileData.keyValueMetadata().contains("QT_IBL_BAKER_VERSION")) { + Q_ASSERT(texFileData.numFaces() == 6); + Q_ASSERT(texFileData.numLevels() >= 5); + + QRhiTexture *environmentCubeMap = rhi->newTexture(rhiFormat, size, 1, QRhiTexture::CubeMap | QRhiTexture::MipMapped); + environmentCubeMap->setName(debugObjectName.toLatin1()); + environmentCubeMap->create(); + texture.m_texture = environmentCubeMap; + context->registerTexture(texture.m_texture); + if (wasTextureCreated) + *wasTextureCreated = true; + // If we get this far then we need to create an environment map at runtime. + } else if (createEnvironmentMap(inTexture, &texture, debugObjectName)) { + context->registerTexture(texture.m_texture); + if (wasTextureCreated) + *wasTextureCreated = true; + return true; + } else { + qWarning() << "Failed to create environment map"; + return false; + } + } else { + if (inMipMode == MipModeEnable && mipmapCount == 1) { + textureFlags |= QRhiTexture::Flag::UsedWithGenerateMips; + generateMipmaps = true; + mipmapCount = rhi->mipLevelsForSize(size); + } + + if (mipmapCount > 1) + textureFlags |= QRhiTexture::Flag::MipMapped; + + if (inFlags.testFlag(CubeMap)) + textureFlags |= QRhiTexture::CubeMap; + + texture.m_texture = rhi->newTexture(rhiFormat, size, textureSampleCount, textureFlags); + + texture.m_texture->setName(debugObjectName.toLatin1()); + texture.m_texture->create(); + context->registerTexture(texture.m_texture); + if (wasTextureCreated) + *wasTextureCreated = true; + } + } + + // Update resources + if (inMipMode == MipModeBsdf && (inTexture->data || texFileData.isValid())) { + if (texFileData.isValid() && texFileData.keyValueMetadata().contains("QT_IBL_BAKER_VERSION")) { + const int faceCount = texFileData.numFaces(); for (int layer = 0; layer < faceCount; ++layer) { for (int level = 0; level < mipmapCount; ++level) { QRhiTextureSubresourceUploadDescription subDesc; subDesc.setSourceSize(sizeForMipLevel(level, size)); - subDesc.setData(tex.getDataView(level, layer).toByteArray()); + subDesc.setData(texFileData.getDataView(level, layer).toByteArray()); textureUploads << QRhiTextureUploadEntry { layer, level, subDesc }; } } - texture.m_texture = environmentCubeMap; QRhiTextureUploadDescription uploadDescription; uploadDescription.setEntries(textureUploads.cbegin(), textureUploads.cend()); auto *rub = rhi->nextResourceUpdateBatch(); - rub->uploadTexture(environmentCubeMap, uploadDescription); + rub->uploadTexture(texture.m_texture, uploadDescription); context->commandBuffer()->resourceUpdate(rub); texture.m_mipmapCount = mipmapCount; - context->registerTexture(texture.m_texture); - return true; - } - - // If we get this far then we need to create an environment map at runtime. - if (createEnvironmentMap(inTexture, &texture, debugObjectName)) { - context->registerTexture(texture.m_texture); return true; - } else { - qWarning() << "Failed to create environment map"; - return false; } - } else if (inTexture->textureFileData.isValid()) { - const QTextureFileData &tex = inTexture->textureFileData; - size = tex.size(); - mipmapCount = tex.numLevels(); - + } else if (texFileData.isValid()) { int numFaces = 1; // Just having a container with 6 faces is not enough, we only treat it // as a cubemap if it was requested to be treated as such. Otherwise // only face 0 is used. - if (tex.numFaces() == 6 && inFlags.testFlag(CubeMap)) + if (texFileData.numFaces() == 6 && inFlags.testFlag(CubeMap)) numFaces = 6; - for (int level = 0; level < tex.numLevels(); ++level) { + for (int level = 0; level < texFileData.numLevels(); ++level) { QRhiTextureSubresourceUploadDescription subDesc; subDesc.setSourceSize(sizeForMipLevel(level, size)); for (int face = 0; face < numFaces; ++face) { - subDesc.setData(tex.getDataView(level, face).toByteArray()); + subDesc.setData(texFileData.getDataView(level, face).toByteArray()); textureUploads << QRhiTextureUploadEntry{ face, level, subDesc }; } } - - rhiFormat = toRhiFormat(inTexture->format.format); if (checkTransp) { - auto glFormat = tex.glInternalFormat() ? tex.glInternalFormat() : tex.glFormat(); + auto glFormat = texFileData.glInternalFormat() ? texFileData.glInternalFormat() : texFileData.glFormat(); hasTransp = !QSGCompressedTexture::formatIsOpaque(glFormat); } } else { QRhiTextureSubresourceUploadDescription subDesc; if (!inTexture->image.isNull()) { - rhiFormat = toRhiFormat(inTexture->format.format); - size = inTexture->image.size(); subDesc.setImage(inTexture->image); if (checkTransp) hasTransp = QImageData::get(inTexture->image)->checkForAlphaPixels(); } else if (inTexture->data) { - rhiFormat = toRhiFormat(inTexture->format.format); - size = QSize(inTexture->width, inTexture->height); QByteArray buf(static_cast<const char *>(inTexture->data), qMax(0, int(inTexture->dataSizeInBytes))); subDesc.setData(buf); if (checkTransp) hasTransp = inTexture->scanForTransparency(); - } subDesc.setSourceSize(size); if (!subDesc.data().isEmpty() || !subDesc.image().isNull()) @@ -1006,19 +1036,6 @@ bool QSSGBufferManager::createRhiTexture(QSSGRenderImageTexture &texture, const auto validTexSize = size.width() <= maxTextureSize && size.height() <= maxTextureSize; QSSG_ASSERT_X(validTexSize, qPrintable(textureSizeWarning(size, maxTextureSize)), return false); - bool generateMipmaps = false; - if (inMipMode == MipModeEnable && mipmapCount == 1) { - textureFlags |= QRhiTexture::Flag::UsedWithGenerateMips; - generateMipmaps = true; - mipmapCount = rhi->mipLevelsForSize(size); - } - - if (mipmapCount > 1) - textureFlags |= QRhiTexture::Flag::MipMapped; - - if (inFlags.testFlag(CubeMap)) - textureFlags |= QRhiTexture::CubeMap; - if (textureUploads.isEmpty() || size.isEmpty() || rhiFormat == QRhiTexture::UnknownFormat) { qWarning() << "Could not load texture"; return false; @@ -1027,28 +1044,20 @@ bool QSSGBufferManager::createRhiTexture(QSSGRenderImageTexture &texture, return false; } - auto *tex = rhi->newTexture(rhiFormat, size, textureSampleCount, textureFlags); - - QSSG_ASSERT(tex != nullptr, return false); - - tex->setName(debugObjectName.toLatin1()); - tex->create(); + QSSG_ASSERT(texture.m_texture != nullptr, return false); if (checkTransp) texture.m_flags.setHasTransparency(hasTransp); - texture.m_texture = tex; QRhiTextureUploadDescription uploadDescription; uploadDescription.setEntries(textureUploads.cbegin(), textureUploads.cend()); auto *rub = rhi->nextResourceUpdateBatch(); // TODO: optimize - rub->uploadTexture(tex, uploadDescription); + rub->uploadTexture(texture.m_texture, uploadDescription); if (generateMipmaps) - rub->generateMips(tex); + rub->generateMips(texture.m_texture); context->commandBuffer()->resourceUpdate(rub); texture.m_mipmapCount = mipmapCount; - - context->registerTexture(texture.m_texture); // owned by the QSSGRhiContext from here on return true; } diff --git a/src/runtimerender/resourcemanager/qssgrenderbuffermanager_p.h b/src/runtimerender/resourcemanager/qssgrenderbuffermanager_p.h index ecf7a352..aee89b9e 100644 --- a/src/runtimerender/resourcemanager/qssgrenderbuffermanager_p.h +++ b/src/runtimerender/resourcemanager/qssgrenderbuffermanager_p.h @@ -187,11 +187,12 @@ private: CubeMap = 0x02 }; Q_DECLARE_FLAGS(CreateRhiTextureFlags, CreateRhiTextureFlag) - bool createRhiTexture(QSSGRenderImageTexture &texture, - const QSSGLoadedTexture *inTexture, - MipMode inMipMode, - CreateRhiTextureFlags inFlags, - const QString &debugObjectName); + bool setRhiTexture(QSSGRenderImageTexture &texture, + const QSSGLoadedTexture *inTexture, + MipMode inMipMode, + CreateRhiTextureFlags inFlags, + const QString &debugObjectName, + bool *wasTextureCreated = nullptr); QSSGRenderMesh *loadRenderMesh(const QSSGRenderPath &inSourcePath, QSSGMeshProcessingOptions options); QSSGRenderMesh *loadRenderMesh(QSSGRenderGeometry *geometry, QSSGMeshProcessingOptions options); diff --git a/tests/manual/dynamic3DTest/CMakeLists.txt b/tests/manual/dynamic3DTest/CMakeLists.txt index cb2f364d..b7fe289a 100644 --- a/tests/manual/dynamic3DTest/CMakeLists.txt +++ b/tests/manual/dynamic3DTest/CMakeLists.txt @@ -14,6 +14,7 @@ qt_internal_add_manual_test(manual_test_dynamic3DTest set(qml_resource_files "main.qml" + "RiggedFigure.qml" "random1.mesh" "random2.mesh" "random3.mesh" @@ -23,6 +24,7 @@ set(qml_resource_files "noise3.jpg" "noise4.jpg" "noise5.jpg" + "riggedfigure.mesh" ) qt_internal_add_resource(manual_test_dynamic3DTest "qml" diff --git a/tests/manual/dynamic3DTest/RiggedFigure.qml b/tests/manual/dynamic3DTest/RiggedFigure.qml new file mode 100644 index 00000000..09d966bd --- /dev/null +++ b/tests/manual/dynamic3DTest/RiggedFigure.qml @@ -0,0 +1,545 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only + +import QtQuick +import QtQuick3D + +import QtQuick.Timeline + +Node { + id: node + + // Resources + PrincipledMaterial { + id: default_effect_material + objectName: "Default-effect" + baseColor: "#ffcccccc" + roughness: 1 + alphaMode: PrincipledMaterial.Opaque + } + Skin { + id: skin + joints: [ + torso_joint_1, + torso_joint_2, + torso_joint_3, + neck_joint_1, + neck_joint_2, + arm_joint_L_1, + arm_joint_R_1, + arm_joint_L_2, + arm_joint_R_2, + arm_joint_L_3, + arm_joint_R_3, + leg_joint_L_1, + leg_joint_R_1, + leg_joint_L_2, + leg_joint_R_2, + leg_joint_L_3, + leg_joint_R_3, + leg_joint_L_5, + leg_joint_R_5 + ] + inverseBindPoses: [ + Qt.matrix4x4(0.999983, 0.000442018, 0.00581419, -0.00398856, 0, 0.997123, -0.0758045, 0.0520021, -0.005831, 0.0758032, 0.997106, -0.684015, 0, 0, 0, 1), + Qt.matrix4x4(1, 0, 0, 0, 0, -0.01376, 0.999905, -0.85674, 0, -0.999905, -0.0137601, 0.024791, 0, 0, 0, 1), + Qt.matrix4x4(1, 0, 0, 0, 0, 0.979842, 0.199774, -0.224555, 0, -0.199774, 0.979842, -1.05133, 0, 0, 0, 1), + Qt.matrix4x4(1, 0, 0, 0, 0, -0.00751853, 0.999972, -1.12647, 0, -0.999972, -0.00751847, 0.00796944, 0, 0, 0, 1), + Qt.matrix4x4(-1, -1.50995e-07, 0, 0, 0, 0.00364935, 0.999993, -1.19299, -1.51869e-07, 0.999993, -0.00364941, 0.00535393, 0, 0, 0, 1), + Qt.matrix4x4(-0.0623881, 0.998036, -0.00569177, 0.00162297, 0.891518, 0.0531644, -0.449853, 0.404156, -0.448667, -0.0331397, -0.893084, 0.998987, 0, 0, 0, 1), + Qt.matrix4x4(0.109672, 0.988876, -0.100484, 0.107683, -0.891521, 0.0531632, -0.449849, 0.404152, -0.439503, 0.13892, 0.887434, -0.993169, 0, 0, 0, 1), + Qt.matrix4x4(0.530194, 0.847874, 0.001751, -0.183428, 0.760039, -0.474352, -0.444218, 0.206564, -0.375811, 0.236853, -0.895917, 0.973213, 0, 0, 0, 1), + Qt.matrix4x4(-0.0705104, -0.619322, 0.781965, -0.761146, -0.760038, -0.474352, -0.444223, 0.206569, 0.646043, -0.625645, -0.437261, 0.633599, 0, 0, 0, 1), + Qt.matrix4x4(0.631434, 0.775418, -0.00419003, -0.228155, 0.649284, -0.53166, -0.543845, 0.154659, -0.423935, 0.340682, -0.839175, 0.951451, 0, 0, 0, 1), + Qt.matrix4x4(0.111378, -0.773831, 0.623523, -0.550204, -0.649284, -0.531661, -0.543845, 0.15466, 0.752347, -0.344271, -0.561651, 0.809067, 0, 0, 0, 1), + Qt.matrix4x4(-0.830471, -0.549474, 0.091635, -0.00030848, 0.0339727, -0.214148, -0.97621, 0.596867, 0.556025, -0.807601, 0.196511, -0.159297, 0, 0, 0, 1), + Qt.matrix4x4(-0.994689, 0.102198, 0.0121981, -0.0750653, -0.0339737, -0.214147, -0.97621, 0.596867, -0.0971548, -0.97144, 0.216482, -0.140501, 0, 0, 0, 1), + Qt.matrix4x4(-0.99973, 0.0232223, -7.82996e-05, 0.0784336, 0.0051282, 0.217484, -0.97605, 0.357951, -0.0226493, -0.975788, -0.217544, 0.0222206, 0, 0, 0, 1), + Qt.matrix4x4(-0.998171, -0.0599068, -0.00810355, -0.0775425, -0.00512856, 0.217484, -0.97605, 0.357951, 0.0602345, -0.974224, -0.217393, 0.0251548, 0, 0, 0, 1), + Qt.matrix4x4(-0.999327, 0.0366897, 0, 0.0783684, 0.0287104, 0.781987, 0.622632, -0.0567413, 0.0228442, 0.622213, -0.782514, 0.0634761, 0, 0, 0, 1), + Qt.matrix4x4(-0.999326, 0.00828946, 0.0357652, -0.0814984, 0.0287402, 0.782804, 0.621604, -0.0521458, -0.0228444, 0.622213, -0.782514, 0.0634761, 0, 0, 0, 1), + Qt.matrix4x4(0.994013, 0.109264, 0.000418345, -0.0755577, 0.109252, -0.993835, -0.0188101, -0.0405796, -0.00164008, 0.0187438, -0.999822, 0.0227357, 0, 0, 0, 1), + Qt.matrix4x4(0.994011, -0.109281, 0.000483894, 0.0755372, -0.109253, -0.993836, -0.018811, -0.0405797, 0.00253636, 0.0186453, -0.999823, 0.0228038, 0, 0, 0, 1) + ] + } + + // Nodes: + Node { + id: z_UP + objectName: "Z_UP" + rotation: Qt.quaternion(0.707107, -0.707107, 0, 0) + Node { + id: armature + objectName: "Armature" + Node { + id: torso_joint_1 + objectName: "torso_joint_1" + position: Qt.vector3d(2.79397e-09, -1.41566e-07, 0.686) + rotation: Qt.quaternion(0.999276, -0.0379294, -0.00291343, 0.000110585) + scale: Qt.vector3d(1, 1, 1) + Node { + id: torso_joint_2 + objectName: "torso_joint_2" + position: Qt.vector3d(0.000999981, -4.84288e-08, 0.171491) + rotation: Qt.quaternion(0.674713, 0.738075, 0.00196715, -0.00215189) + scale: Qt.vector3d(1, 1, 1) + Node { + id: torso_joint_3 + objectName: "torso_joint_3" + position: Qt.vector3d(0, 0.218018, 3.72529e-09) + rotation: Qt.quaternion(0.770153, -0.637859, 4.25872e-10, 3.52719e-10) + scale: Qt.vector3d(1, 1, 1) + Node { + id: neck_joint_1 + objectName: "neck_joint_1" + position: Qt.vector3d(0, 7.45058e-08, 0.0525597) + rotation: Qt.quaternion(0.77214, 0.635452, 1.03679e-15, 8.51267e-16) + Node { + id: neck_joint_2 + objectName: "neck_joint_2" + position: Qt.vector3d(0, 0.0665059, 0) + rotation: Qt.quaternion(-7.54967e-08, 4.21579e-10, 0.999984, -0.00558399) + scale: Qt.vector3d(1, 1, 1) + } + } + Node { + id: arm_joint_L_1 + objectName: "arm_joint_L_1" + position: Qt.vector3d(0.0880006, -0.000199288, -0.000977397) + rotation: Qt.quaternion(-0.0885639, 0.678942, 0.687945, -0.240678) + scale: Qt.vector3d(1, 1, 1) + Node { + id: arm_joint_L_2 + objectName: "arm_joint_L_2" + position: Qt.vector3d(1.86265e-09, 0.244526, -5.96046e-08) + rotation: Qt.quaternion(0.952132, -0.00240006, 0.139812, 0.271831) + Node { + id: arm_joint_L_3 + objectName: "arm_joint_L_3" + position: Qt.vector3d(0, 0.185517, 0) + rotation: Qt.quaternion(0.996411, 0.0572906, 0.0282273, 0.0555599) + scale: Qt.vector3d(1, 1, 1) + } + } + } + Node { + id: arm_joint_R_1 + objectName: "arm_joint_R_1" + position: Qt.vector3d(-0.0880006, -0.000199288, -0.000977397) + rotation: Qt.quaternion(0.69168, -0.276431, -0.0518638, 0.665187) + scale: Qt.vector3d(1, 1, 1) + Node { + id: arm_joint_R_2 + objectName: "arm_joint_R_2" + position: Qt.vector3d(-7.45058e-09, 0.244526, -5.96046e-08) + rotation: Qt.quaternion(-0.314075, -0.228006, 0.909648, -0.148023) + scale: Qt.vector3d(1, 0.999999, 1) + Node { + id: arm_joint_R_3 + objectName: "arm_joint_R_3" + position: Qt.vector3d(-5.96046e-08, 0.185517, 0) + rotation: Qt.quaternion(0.986567, 0.0785489, -0.142535, 0.0141023) + scale: Qt.vector3d(1, 1, 1) + } + } + } + } + } + Node { + id: leg_joint_L_1 + objectName: "leg_joint_L_1" + position: Qt.vector3d(0.0676193, 0.00446109, -0.0722646) + rotation: Qt.quaternion(-0.201112, 0.210881, -0.624331, 0.724772) + scale: Qt.vector3d(1, 1, 1) + Node { + id: leg_joint_L_2 + objectName: "leg_joint_L_2" + position: Qt.vector3d(0, 0.266112, 0) + rotation: Qt.quaternion(0.929599, -0.211154, 0.298432, 0.046886) + scale: Qt.vector3d(1, 1, 1) + Node { + id: leg_joint_L_3 + objectName: "leg_joint_L_3" + position: Qt.vector3d(0, 0.275824, 0) + rotation: Qt.quaternion(0.530323, -0.847769, 0.00228158, 0.00633871) + scale: Qt.vector3d(1, 1, 1) + Node { + id: leg_joint_L_5 + objectName: "leg_joint_L_5" + position: Qt.vector3d(-0.00234649, -0.0661733, 0.0278568) + rotation: Qt.quaternion(0.0687815, 0.0245321, -0.319997, 0.9446) + scale: Qt.vector3d(1, 1, 1) + } + } + } + } + Node { + id: leg_joint_R_1 + objectName: "leg_joint_R_1" + position: Qt.vector3d(-0.0684572, 0.00446085, -0.0714711) + rotation: Qt.quaternion(0.0466302, -0.0233987, -0.654264, 0.754465) + scale: Qt.vector3d(1, 1, 1) + Node { + id: leg_joint_R_2 + objectName: "leg_joint_R_2" + position: Qt.vector3d(0, 0.266112, 1.49012e-08) + rotation: Qt.quaternion(0.972955, -0.216061, -0.0810801, 0.01008) + Node { + id: leg_joint_R_3 + objectName: "leg_joint_R_3" + position: Qt.vector3d(-7.45058e-09, 0.275824, -3.72529e-09) + rotation: Qt.quaternion(0.529777, -0.847167, 0.0320483, 0.0248404) + scale: Qt.vector3d(1, 1, 1) + Node { + id: leg_joint_R_5 + objectName: "leg_joint_R_5" + position: Qt.vector3d(-0.00145853, -0.0661987, 0.0278568) + rotation: Qt.quaternion(-0.0414683, -0.0341433, -0.319178, 0.946171) + scale: Qt.vector3d(0.999999, 0.999999, 0.999999) + } + } + } + } + } + } + Model { + id: proxy + objectName: "Proxy" + source: "riggedfigure.mesh" + skin: skin + materials: [ + default_effect_material + ] + } + } + + // Animations: + Timeline { + id: timeline0 + objectName: "timeline0" + property real framesPerSecond: 1000 + startFrame: 0 + endFrame: 1250 + currentFrame: 0 + enabled: true + animations: TimelineAnimation { + duration: 1250 + from: 0 + to: 1250 + running: true + loops: Animation.Infinite + } + KeyframeGroup { + target: leg_joint_R_5 + property: "position" + Keyframe { + frame: 0 + value: Qt.vector3d(-0.00145852, -0.0661988, 0.0278567) + } + } + KeyframeGroup { + target: leg_joint_R_5 + property: "rotation" + Keyframe { + frame: 0 + value: Qt.quaternion(-0.0414678, -0.0341418, -0.319178, 0.946171) + } + } + KeyframeGroup { + target: leg_joint_R_3 + property: "position" + Keyframe { + frame: 0 + value: Qt.vector3d(7.45058e-09, 0.275824, -7.45058e-09) + } + } + KeyframeGroup { + target: leg_joint_R_3 + property: "rotation" + Keyframe { + frame: 0 + value: Qt.quaternion(-0.529778, 0.847166, -0.0320483, -0.0248404) + } + } + KeyframeGroup { + target: leg_joint_R_2 + property: "position" + Keyframe { + frame: 0 + value: Qt.vector3d(7.45058e-09, 0.266112, 0) + } + } + KeyframeGroup { + target: leg_joint_R_2 + property: "rotation" + Keyframe { + frame: 0 + value: Qt.quaternion(-0.972956, 0.216062, 0.0810801, -0.01008) + } + } + KeyframeGroup { + target: leg_joint_R_1 + property: "position" + Keyframe { + frame: 0 + value: Qt.vector3d(-0.0684572, 0.00446077, -0.0714709) + } + } + KeyframeGroup { + target: leg_joint_R_1 + property: "rotation" + Keyframe { + frame: 0 + value: Qt.quaternion(0.0466288, -0.0234008, -0.654263, 0.754465) + } + } + KeyframeGroup { + target: leg_joint_L_5 + property: "position" + Keyframe { + frame: 0 + value: Qt.vector3d(-0.00234646, -0.0661734, 0.0278567) + } + } + KeyframeGroup { + target: leg_joint_L_5 + property: "rotation" + Keyframe { + frame: 0 + value: Qt.quaternion(0.0687827, 0.0245355, -0.319997, 0.9446) + } + } + KeyframeGroup { + target: leg_joint_L_3 + property: "position" + Keyframe { + frame: 0 + value: Qt.vector3d(0, 0.275824, -1.86265e-09) + } + } + KeyframeGroup { + target: leg_joint_L_3 + property: "rotation" + Keyframe { + frame: 0 + value: Qt.quaternion(-0.530324, 0.847768, -0.00228158, -0.0063387) + } + } + KeyframeGroup { + target: leg_joint_L_2 + property: "position" + Keyframe { + frame: 0 + value: Qt.vector3d(0, 0.266112, 1.49012e-08) + } + } + KeyframeGroup { + target: leg_joint_L_2 + property: "rotation" + Keyframe { + frame: 0 + value: Qt.quaternion(-0.929599, 0.211155, -0.298433, -0.046886) + } + } + KeyframeGroup { + target: leg_joint_L_1 + property: "position" + Keyframe { + frame: 0 + value: Qt.vector3d(0.067619, 0.00446084, -0.0722642) + } + } + KeyframeGroup { + target: arm_joint_R_3 + property: "position" + Keyframe { + frame: 0 + value: Qt.vector3d(0, 0.185517, 0) + } + } + KeyframeGroup { + target: arm_joint_R_3 + property: "rotation" + Keyframe { + frame: 0 + value: Qt.quaternion(-0.986567, -0.078549, 0.142535, -0.0141023) + } + } + KeyframeGroup { + target: arm_joint_R_2 + property: "position" + Keyframe { + frame: 0 + value: Qt.vector3d(-7.45058e-09, 0.244526, 0) + } + } + KeyframeGroup { + target: arm_joint_L_3 + property: "position" + Keyframe { + frame: 0 + value: Qt.vector3d(0, 0.185517, 5.96046e-08) + } + } + KeyframeGroup { + target: arm_joint_L_3 + property: "rotation" + Keyframe { + frame: 0 + value: Qt.quaternion(-0.996411, -0.0572907, -0.0282272, -0.0555601) + } + } + KeyframeGroup { + target: arm_joint_L_2 + property: "position" + Keyframe { + frame: 0 + value: Qt.vector3d(-2.32831e-09, 0.244526, 0) + } + } + KeyframeGroup { + target: arm_joint_L_2 + property: "rotation" + Keyframe { + frame: 0 + value: Qt.quaternion(-0.952132, 0.00239999, -0.139812, -0.271831) + } + } + KeyframeGroup { + target: arm_joint_L_1 + property: "position" + Keyframe { + frame: 0 + value: Qt.vector3d(0.0880001, -0.00019978, -0.0009799) + } + Keyframe { + frame: 1250 + value: Qt.vector3d(0.0879999, -0.000199795, -0.00098002) + } + } + KeyframeGroup { + target: arm_joint_L_1 + property: "rotation" + Keyframe { + frame: 0 + value: Qt.quaternion(-0.321235, 0.618298, 0.538041, -0.474371) + } + Keyframe { + frame: 1250 + value: Qt.quaternion(-0.0885618, 0.678943, 0.687945, -0.240675) + } + } + KeyframeGroup { + target: neck_joint_2 + property: "position" + Keyframe { + frame: 0 + value: Qt.vector3d(-5.32907e-15, 0.0665059, 9.31323e-10) + } + } + KeyframeGroup { + target: neck_joint_2 + property: "rotation" + Keyframe { + frame: 0 + value: Qt.quaternion(-1.1912e-07, -5.47696e-10, 0.999487, 0.0320266) + } + Keyframe { + frame: 1250 + value: Qt.quaternion(-1.19207e-07, 6.65661e-10, 0.999984, -0.00558399) + } + } + KeyframeGroup { + target: neck_joint_1 + property: "position" + Keyframe { + frame: 0 + value: Qt.vector3d(-8.88178e-15, -1.49012e-08, 0.0525595) + } + Keyframe { + frame: 1250 + value: Qt.vector3d(-8.88178e-15, -4.47035e-08, 0.0525594) + } + } + KeyframeGroup { + target: neck_joint_1 + property: "rotation" + Keyframe { + frame: 0 + value: Qt.quaternion(-0.686502, -0.727128, 6.39277e-11, -1.96486e-11) + } + Keyframe { + frame: 1250 + value: Qt.quaternion(-0.77214, -0.635453, 1.20456e-13, 1.01944e-13) + } + } + KeyframeGroup { + target: torso_joint_2 + property: "position" + Keyframe { + frame: 0 + value: Qt.vector3d(0.000999983, -1.86265e-08, 0.171491) + } + } + KeyframeGroup { + target: torso_joint_2 + property: "rotation" + Keyframe { + frame: 0 + value: Qt.quaternion(-0.674713, -0.738074, -0.00196715, 0.00215188) + } + } + KeyframeGroup { + target: torso_joint_3 + property: "position" + Keyframe { + frame: 0 + value: Qt.vector3d(-7.10543e-15, 0.218018, -1.86265e-09) + } + } + KeyframeGroup { + target: torso_joint_3 + property: "rotation" + Keyframe { + frame: 0 + value: Qt.quaternion(-0.770153, 0.637859, -4.26135e-10, -3.52842e-10) + } + } + KeyframeGroup { + target: arm_joint_R_1 + property: "position" + Keyframe { + frame: 0 + value: Qt.vector3d(-0.0880001, -0.000199795, -0.00098002) + } + } + KeyframeGroup { + target: arm_joint_R_1 + property: "rotation" + Keyframe { + frame: 0 + value: Qt.quaternion(-0.611424, 0.495758, 0.309245, -0.533621) + } + Keyframe { + frame: 1250 + value: Qt.quaternion(-0.691681, 0.276426, 0.0518633, -0.665189) + } + } + KeyframeGroup { + target: torso_joint_1 + property: "position" + Keyframe { + frame: 0 + value: Qt.vector3d(4.58966e-10, -1.15066e-07, 0.686) + } + } + KeyframeGroup { + target: torso_joint_1 + property: "rotation" + Keyframe { + frame: 0 + value: Qt.quaternion(-0.999276, 0.0379299, 0.00291355, -0.000113405) + } + } + } +} diff --git a/tests/manual/dynamic3DTest/main.qml b/tests/manual/dynamic3DTest/main.qml index bd16f590..71c8cd68 100644 --- a/tests/manual/dynamic3DTest/main.qml +++ b/tests/manual/dynamic3DTest/main.qml @@ -65,6 +65,7 @@ Window { property var spotLights: [] property var cameras: [] property var models: [] + property var riggedModels: [] property var dynamicModels: [] property var dynamicGeometries: [] property var textures: [] @@ -78,6 +79,7 @@ Window { property int spotLightsCount: 0 property int camerasCount: 0 property int modelsCount: 0 + property int riggedModelsCount: 0 property int dynamicModelsCount: 0 property int texturesCount: 0 property int dynamicTexturesCount: 0 @@ -126,6 +128,13 @@ Window { } Component { + id: riggedModel + RiggedFigure { + + } + } + + Component { id: dynamicModel Model { property alias color: material.baseColor @@ -253,6 +262,15 @@ Window { return sources[index] } + function getRiggedMeshSource() { + let sources = [ + "riggedfigure.mesh", + "riggedsimple.mesh" + ] + let index = Math.floor(Math.random() * sources.length); + return sources[index] + } + function getImageSource() { let sources = [ "noise1.jpg", @@ -341,6 +359,22 @@ Window { } } + function addRiggedModel() { + let position = getRandomVector3d(objectSpawner.range) + let rotation = getRandomVector3d(360) + let instance = riggedModel.createObject(objectSpawner, { "position": position, "eulerRotation": rotation}) + riggedModels.push(instance); + riggedModelsCount++ + } + + function removeRiggedModel() { + if (riggedModels.length > 0) { + let instance = riggedModels.pop(); + instance.destroy(); + riggedModelsCount-- + } + } + function addDynamicModel() { let position = getRandomVector3d(objectSpawner.range) let rotation = getRandomVector3d(360) @@ -459,6 +493,7 @@ Window { // reset the model sources models.forEach(model => model.source = getMeshSource()) } + function changeDynamicModels() { // reset the dynamic model sources if (dynamicModels.length == 0) @@ -712,6 +747,30 @@ Window { } RowLayout { Label { + text: "Rigged Model" + color: "white" + Layout.fillWidth: true + } + Label { + text: objectSpawner.riggedModelsCount + color: "white" + Layout.fillWidth: true + } + ToolButton { + text: "+" + onClicked: { + objectSpawner.addRiggedModel() + } + } + ToolButton { + text: "-" + onClicked: { + objectSpawner.removeRiggedModel() + } + } + } + RowLayout { + Label { text: "Dynamic Model" color: "white" Layout.fillWidth: true diff --git a/tests/manual/dynamic3DTest/qml.qrc b/tests/manual/dynamic3DTest/qml.qrc index 8d87394b..fcd11b80 100644 --- a/tests/manual/dynamic3DTest/qml.qrc +++ b/tests/manual/dynamic3DTest/qml.qrc @@ -10,5 +10,7 @@ <file>noise3.jpg</file> <file>noise4.jpg</file> <file>noise5.jpg</file> + <file>RiggedFigure.qml</file> + <file>riggedfigure.mesh</file> </qresource> </RCC> diff --git a/tests/manual/dynamic3DTest/riggedfigure.mesh b/tests/manual/dynamic3DTest/riggedfigure.mesh Binary files differnew file mode 100644 index 00000000..72ddbb61 --- /dev/null +++ b/tests/manual/dynamic3DTest/riggedfigure.mesh |
