Commit 89661913 authored by Qt Forward Merge Bot's avatar Qt Forward Merge Bot
Browse files

Merge remote-tracking branch 'origin/5.15' into dev

Change-Id: I45be7ae8399e3b27d1ac55ccfed2fa42a872ac23
parents ecbf5e9a 3c551b2e
......@@ -48,12 +48,12 @@
**
****************************************************************************/
import Qt3D.Core 2.0
import Qt3D.Render 2.0
import Qt3D.Input 2.0
import Qt3D.Extras 2.0
import Qt3D.Core 2.14
import Qt3D.Render 2.14
import Qt3D.Input 2.14
import Qt3D.Extras 2.14
import QtQuick 2.0 as QQ2
import QtQuick 2.14 as QQ2
Entity {
......@@ -79,7 +79,7 @@ Entity {
activeFrameGraph: ForwardRenderer {
camera: camera
clearColor: "transparent"
clearBuffers: sceneRoot.clearColor ? ClearBuffers.ColorDepthBuffer : ClearBuffers.DepthBuffer
buffersToClear: sceneRoot.clearColor ? ClearBuffers.ColorDepthBuffer : ClearBuffers.DepthBuffer
}
},
InputSettings { }
......
/****************************************************************************
**
** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt3D module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** 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 http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "abstractevaluateclipanimatorjob_p.h"
#include <Qt3DCore/private/qaspectjob_p.h>
#include <Qt3DCore/private/qaspectmanager_p.h>
#include <Qt3DCore/private/qskeleton_p.h>
#include <Qt3DAnimation/qabstractclipanimator.h>
QT_BEGIN_NAMESPACE
namespace Qt3DAnimation {
namespace Animation {
class AbstractEvaluateClipAnimatorJobPrivate : public Qt3DCore::QAspectJobPrivate
{
public:
AbstractEvaluateClipAnimatorJobPrivate() { }
~AbstractEvaluateClipAnimatorJobPrivate() override { }
void postFrame(Qt3DCore::QAspectManager *manager) override;
Q_DECLARE_PUBLIC(AbstractEvaluateClipAnimatorJob)
AnimationRecord m_record;
QVector<AnimationCallbackAndValue> m_callbacks;
private:
AbstractEvaluateClipAnimatorJob *q_ptr;
};
AbstractEvaluateClipAnimatorJob::AbstractEvaluateClipAnimatorJob()
: Qt3DCore::QAspectJob(*new AbstractEvaluateClipAnimatorJobPrivate)
{
}
void AbstractEvaluateClipAnimatorJob::setPostFrameData(const AnimationRecord &record, const QVector<AnimationCallbackAndValue> &callbacks)
{
auto mainThreadCB = callbacks;
mainThreadCB.erase(std::remove_if(mainThreadCB.begin(), mainThreadCB.end(), [](const AnimationCallbackAndValue &callback) {
if (callback.flags.testFlag(QAnimationCallback::OnThreadPool)) {
// call these now and remove them from the list
callback.callback->valueChanged(callback.value);
return true;
}
return false;
}), mainThreadCB.end());
// Should now only have callbacks to be called on main thread
Q_D(AbstractEvaluateClipAnimatorJob);
d->m_record = record;
d->m_callbacks = mainThreadCB;
}
void AbstractEvaluateClipAnimatorJobPrivate::postFrame(Qt3DCore::QAspectManager *manager)
{
if (m_record.animatorId.isNull())
return;
for (auto targetData : qAsConst(m_record.targetChanges)) {
Qt3DCore::QNode *node = manager->lookupNode(targetData.targetId);
if (node)
node->setProperty(targetData.propertyName, targetData.value);
}
for (auto skeletonData : qAsConst(m_record.skeletonChanges)) {
Qt3DCore::QAbstractSkeleton *node = qobject_cast<Qt3DCore::QAbstractSkeleton *>(manager->lookupNode(skeletonData.first));
if (node) {
auto d = Qt3DCore::QAbstractSkeletonPrivate::get(node);
d->m_localPoses = skeletonData.second;
d->update();
}
}
QAbstractClipAnimator *animator = qobject_cast<QAbstractClipAnimator *>(manager->lookupNode(m_record.animatorId));
if (animator) {
if (isValidNormalizedTime(m_record.normalizedTime))
animator->setNormalizedTime(m_record.normalizedTime);
if (m_record.finalFrame)
animator->setRunning(false);
}
for (const AnimationCallbackAndValue &callback: qAsConst(m_callbacks)) {
if (callback.callback)
callback.callback->valueChanged(callback.value);
}
m_record = {};
}
} // Animation
} // Qt3DAnimation
QT_END_NAMESPACE
/****************************************************************************
**
** Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB).
** Contact: https://www.qt.io/licensing/
** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the Qt3D module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** $QT_BEGIN_LICENSE:LGPL3$
** 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.
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
** will be met: https://www.gnu.org/licenses/lgpl.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** 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-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
** General Public License version 2.0 or later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QT3DRENDER_RENDER_COMMANDTHREAD_P_H
#define QT3DRENDER_RENDER_COMMANDTHREAD_P_H
#ifndef QT3DANIMATION_ANIMATION_ABSTRACTEVALUATECLIPANIMATORJOB_P_H
#define QT3DANIMATION_ANIMATION_ABSTRACTEVALUATECLIPANIMATORJOB_P_H
//
// W A R N I N G
......@@ -51,65 +48,30 @@
// We mean it.
//
#include <QtCore/QThread>
#include <QtCore/QSemaphore>
#include <QtCore/QMutex>
#include <Qt3DCore/qaspectjob.h>
#include <Qt3DAnimation/private/animationutils_p.h>
QT_BEGIN_NAMESPACE
class QOpenGLContext;
namespace Qt3DAnimation {
namespace Animation {
namespace Qt3DRender {
class AbstractEvaluateClipAnimatorJobPrivate;
namespace Render {
class Renderer;
class GLCommand;
class OffscreenSurfaceHelper;
class GraphicsContext;
class ShaderCache;
class CommandThread : public QThread
class AbstractEvaluateClipAnimatorJob : public Qt3DCore::QAspectJob
{
Q_OBJECT
public:
explicit CommandThread(Renderer *renderer);
~CommandThread();
Render::Renderer* renderer() const { return m_renderer; }
void setShaderCache(ShaderCache *shaderCache);
ShaderCache *shaderCache() const { return m_shaderCache; }
protected:
AbstractEvaluateClipAnimatorJob();
void initialize(QOpenGLContext *mainContext, OffscreenSurfaceHelper *offsreenSurfaceHelper);
void shutdown();
void executeCommand(GLCommand *command);
private:
void run() override;
void executeCommandInternal(Qt3DRender::Render::GLCommand *command);
void setPostFrameData(const AnimationRecord &record, const QVector<AnimationCallbackAndValue> &callbacks);
private:
Renderer* m_renderer;
QSemaphore m_waitForStartSemaphore;
QSemaphore m_initializedSemaphore;
QSemaphore m_commandRequestedSemaphore;
QSemaphore m_commandExecutionSemaphore;
QMutex m_blockingCallerMutex;
QOpenGLContext *m_mainContext;
ShaderCache *m_shaderCache;
OffscreenSurfaceHelper *m_offsreenSurfaceHelper;
QScopedPointer<QOpenGLContext> m_localContext;
QScopedPointer<GraphicsContext> m_graphicsContext;
GLCommand *m_currentCommand;
QAtomicInt m_running;
Q_DECLARE_PRIVATE(AbstractEvaluateClipAnimatorJob)
};
} // Render
} // Qt3DRender
} // Animation
} // Qt3DAnimation
QT_END_NAMESPACE
#endif // QT3DRENDER_RENDER_COMMANDTHREAD_P_H
#endif // QT3DANIMATION_ANIMATION_ABSTRACTEVALUATECLIPANIMATORJOB_P_H
......@@ -43,7 +43,6 @@
#include <Qt3DAnimation/private/managers_p.h>
#include <Qt3DAnimation/private/gltfimporter_p.h>
#include <Qt3DRender/private/qurlhelper_p.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
#include <QtCore/qbytearray.h>
#include <QtCore/qfile.h>
......@@ -90,11 +89,6 @@ void AnimationClip::setStatus(QAnimationClipLoader::Status status)
{
if (status != m_status) {
m_status = status;
Qt3DCore::QPropertyUpdatedChangePtr e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId());
e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
e->setPropertyName("status");
e->setValue(QVariant::fromValue(m_status));
notifyObservers(e);
}
}
......@@ -124,7 +118,7 @@ void AnimationClip::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool first
Q_ASSERT(m_dataType == File);
if (m_source != loaderNode->source()) {
m_source = loaderNode->source();
if (m_clipData.isValid())
if (!m_source.isEmpty())
setDirty(Handler::AnimationClipDirty);
}
}
......@@ -317,13 +311,6 @@ void AnimationClip::setDuration(float duration)
return;
m_duration = duration;
// Send a change to the frontend
auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(peerId());
e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
e->setPropertyName("duration");
e->setValue(m_duration);
notifyObservers(e);
}
int AnimationClip::channelIndex(const QString &channelName, int jointIndex) const
......
......@@ -40,8 +40,6 @@
#include <Qt3DAnimation/private/clipblendnode_p.h>
#include <Qt3DAnimation/private/clipblendnodevisitor_p.h>
#include <Qt3DAnimation/private/clipblendvalue_p.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DCore/private/qpropertyupdatedchangebase_p.h>
#include <QtGui/qvector2d.h>
#include <QtGui/qvector3d.h>
#include <QtGui/qvector4d.h>
......@@ -407,13 +405,17 @@ QVariant buildPropertyValue(const MappingData &mappingData, const QVector<float>
return QVariant();
}
QVector<Qt3DCore::QSceneChangePtr> preparePropertyChanges(Qt3DCore::QNodeId animatorId,
const QVector<MappingData> &mappingDataVec,
const QVector<float> &channelResults,
bool finalFrame,
float normalizedLocalTime)
AnimationRecord prepareAnimationRecord(Qt3DCore::QNodeId animatorId,
const QVector<MappingData> &mappingDataVec,
const QVector<float> &channelResults,
bool finalFrame,
float normalizedLocalTime)
{
QVector<Qt3DCore::QSceneChangePtr> changes;
AnimationRecord record;
record.finalFrame = finalFrame;
record.animatorId = animatorId;
record.normalizedTime = normalizedLocalTime;
QVarLengthArray<Skeleton *, 4> dirtySkeletons;
// Iterate over the mappings
......@@ -453,43 +455,14 @@ QVector<Qt3DCore::QSceneChangePtr> preparePropertyChanges(Qt3DCore::QNodeId anim
break;
}
} else {
// TODOSYNC remove once we've found a way to propagate animation changes
// Construct a property update change, set target, property and delivery options
auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(mappingData.targetId);
e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
e->setPropertyName(mappingData.propertyName);
// Handle intermediate updates vs final flag properly
Qt3DCore::QPropertyUpdatedChangeBasePrivate::get(e.data())->m_isIntermediate = !finalFrame;
// Assign new value and send
e->setValue(v);
changes.push_back(e);
record.targetChanges.push_back({mappingData.targetId, mappingData.propertyName, v});
}
}
for (const auto skeleton : dirtySkeletons)
skeleton->sendLocalPoses();
if (isValidNormalizedTime(normalizedLocalTime)) {
// TODOSYNC remove once we've found a way to propagate animation changes
auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(animatorId);
e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
e->setPropertyName("normalizedTime");
e->setValue(normalizedLocalTime);
Qt3DCore::QPropertyUpdatedChangeBasePrivate::get(e.data())->m_isIntermediate = !finalFrame;
changes.push_back(e);
}
// If it's the final frame, notify the frontend that we've stopped
if (finalFrame) {
// TODOSYNC remove once we've found a way to propagate animation changes
auto e = Qt3DCore::QPropertyUpdatedChangePtr::create(animatorId);
e->setDeliveryFlags(Qt3DCore::QSceneChange::DeliverToAll);
e->setPropertyName("running");
e->setValue(false);
changes.push_back(e);
}
record.skeletonChanges.push_back({skeleton->peerId(), skeleton->joints()});
return changes;
return record;
}
QVector<AnimationCallbackAndValue> prepareCallbacks(const QVector<MappingData> &mappingDataVec,
......
......@@ -53,6 +53,7 @@
#include <Qt3DAnimation/qanimationcallback.h>
#include <Qt3DCore/qnodeid.h>
#include <Qt3DCore/qscenechange.h>
#include <Qt3DCore/private/sqt_p.h>
#include <QtCore/qbitarray.h>
#include <QtCore/qdebug.h>
......@@ -183,7 +184,7 @@ struct ChannelNameAndType
case Rotation:
componentCount = 4;
break;
};
}
}
bool operator==(const ChannelNameAndType &rhs) const
......@@ -264,6 +265,32 @@ struct AnimationCallbackAndValue
QVariant value;
};
struct AnimationRecord {
struct TargetChange {
TargetChange(Qt3DCore::QNodeId id, const char *name, QVariant v)
: targetId(id), propertyName(name), value(v) {
}
Qt3DCore::QNodeId targetId;
const char *propertyName = nullptr;
QVariant value;
};
Qt3DCore::QNodeId animatorId;
QVector<TargetChange> targetChanges;
QVector<QPair<Qt3DCore::QNodeId, QVector<Qt3DCore::Sqt>>> skeletonChanges;
float normalizedTime = -1.f;
bool finalFrame = false;
};
Q_AUTOTEST_EXPORT
AnimationRecord prepareAnimationRecord(Qt3DCore::QNodeId animatorId,
const QVector<MappingData> &mappingDataVec,
const QVector<float> &channelResults,
bool finalFrame,
float normalizedLocalTime);
inline constexpr double toSecs(qint64 nsecs) { return nsecs / 1.0e9; }
inline qint64 toNsecs(double seconds) { return qRound64(seconds * 1.0e9); }
......@@ -327,12 +354,6 @@ Q_AUTOTEST_EXPORT
ClipResults evaluateClipAtPhase(AnimationClip *clip,
float phase);
Q_AUTOTEST_EXPORT
QVector<Qt3DCore::QSceneChangePtr> preparePropertyChanges(Qt3DCore::QNodeId animatorId,
const QVector<MappingData> &mappingDataVec,
const QVector<float> &channelResults,
bool finalFrame, float normalizedLocalTime);
Q_AUTOTEST_EXPORT
QVector<AnimationCallbackAndValue> prepareCallbacks(const QVector<MappingData> &mappingDataVec,
const QVector<float> &channelResults);
......@@ -390,5 +411,7 @@ void applyComponentDefaultValues(const QVector<ComponentValue> &componentDefault
QT_END_NAMESPACE
Q_DECLARE_METATYPE(Qt3DAnimation::Animation::AnimationRecord) // LCOV_EXCL_LINE
#endif // QT3DANIMATION_ANIMATION_ANIMATIONUTILS_P_H
......@@ -17,6 +17,7 @@ HEADERS += \
$$PWD/channelmapping_p.h \
$$PWD/channelmapper_p.h \
$$PWD/findrunningclipanimatorsjob_p.h \
$$PWD/abstractevaluateclipanimatorjob_p.h \
$$PWD/evaluateclipanimatorjob_p.h \
$$PWD/clipblendnode_p.h \
$$PWD/clipblendnodevisitor_p.h \
......@@ -43,6 +44,7 @@ SOURCES += \
$$PWD/channelmapping.cpp \
$$PWD/channelmapper.cpp \
$$PWD/findrunningclipanimatorsjob.cpp \
$$PWD/abstractevaluateclipanimatorjob.cpp \
$$PWD/evaluateclipanimatorjob.cpp \
$$PWD/clipblendnode.cpp \
$$PWD/managers.cpp \
......
......@@ -40,8 +40,6 @@
#include <Qt3DAnimation/qclock.h>
#include <Qt3DAnimation/qabstractclipblendnode.h>
#include <Qt3DAnimation/private/qblendedclipanimator_p.h>
#include <Qt3DAnimation/private/qanimationcallbacktrigger_p.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
QT_BEGIN_NAMESPACE
......@@ -123,27 +121,6 @@ void BlendedClipAnimator::setRunning(bool running)
setDirty(Handler::BlendedClipAnimatorDirty);
}
void BlendedClipAnimator::sendPropertyChanges(const QVector<Qt3DCore::QSceneChangePtr> &changes)
{
for (const Qt3DCore::QSceneChangePtr &change : changes)
notifyObservers(change);
}
void BlendedClipAnimator::sendCallbacks(const QVector<AnimationCallbackAndValue> &callbacks)
{
for (const AnimationCallbackAndValue &callback : callbacks) {
if (callback.flags.testFlag(QAnimationCallback::OnThreadPool)) {
callback.callback->valueChanged(callback.value);
} else {
auto e = QAnimationCallbackTriggerPtr::create(peerId());
e->setCallback(callback.callback);
e->setValue(callback.value);
e->setDeliveryFlags(Qt3DCore::QSceneChange::Nodes);
notifyObservers(e);
}
}
}
Qt3DCore::QNodeId BlendedClipAnimator::blendTreeRootId() const
{
......
......@@ -92,9 +92,6 @@ public:
void setMappingData(const QVector<MappingData> &mappingData) { m_mappingData = mappingData; }
QVector<MappingData> mappingData() const { return m_mappingData; }
void sendPropertyChanges(const QVector<Qt3DCore::QSceneChangePtr> &changes);
void sendCallbacks(const QVector<AnimationCallbackAndValue> &callbacks);
void animationClipMarkedDirty() { setDirty(Handler::BlendedClipAnimatorDirty); }
qint64 nsSincePreviousFrame(qint64 currentGlobalTimeNS);
......
......@@ -40,9 +40,6 @@
#include <Qt3DAnimation/private/qchannelmapper_p.h>
#include <Qt3DAnimation/private/animationlogging_p.h>
#include <Qt3DAnimation/private/managers_p.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DCore/qpropertynodeaddedchange.h>
#include <Qt3DCore/qpropertynoderemovedchange.h>
#include <algorithm>
......
......@@ -42,9 +42,6 @@
#include <Qt3DAnimation/private/animationclip_p.h>
#include <Qt3DAnimation/private/managers_p.h>
#include <Qt3DAnimation/private/animationlogging_p.h>
#include <Qt3DAnimation/private/qanimationcallbacktrigger_p.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DCore/private/qpropertyupdatedchangebase_p.h>
QT_BEGIN_NAMESPACE
......@@ -146,27 +143,6 @@ void ClipAnimator::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstT
setDirty(Handler::ClipAnimatorDirty);
}
void ClipAnimator::sendPropertyChanges(const QVector<Qt3DCore::QSceneChangePtr> &changes)
{
for (const Qt3DCore::QSceneChangePtr &change : changes)
notifyObservers(change);
}
void ClipAnimator::sendCallbacks(const QVector<AnimationCallbackAndValue> &callbacks)
{
for (const AnimationCallbackAndValue &callback : callbacks) {
if (callback.flags.testFlag(QAnimationCallback::OnThreadPool)) {
callback.callback->valueChanged(callback.value);
} else {
auto e = QAnimationCallbackTriggerPtr::create(peerId());
e->setCallback(callback.callback);
e->setValue(callback.value);
e->setDeliveryFlags(Qt3DCore::QSceneChange::Nodes);
notifyObservers(e);
}
}
}
qint64 ClipAnimator::nsSincePreviousFrame(qint64 currentGlobalTimeNS)
{
return currentGlobalTimeNS - m_lastGlobalTimeNS;
......
......@@ -93,9 +93,6 @@ public:
int currentLoop() const { return m_currentLoop; }
void setCurrentLoop(int currentLoop) { m_currentLoop = currentLoop; }
void sendPropertyChanges(const QVector<Qt3DCore::QSceneChangePtr> &changes);