summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Strømme <christian.stromme@qt.io>2019-01-09 16:35:05 +0100
committerLaszlo Agocs <laszlo.agocs@qt.io>2019-01-09 16:43:44 +0000
commit85ce7c19c965f3dfdbc3eaf7365e8e6d5dc81a3d (patch)
treeffab010d89bc9e837ff8a64e95957c9375714e8e
parent66a48481616126929ae29a30b316a0dc930e3b2c (diff)
Add support for dynamically adding/removing object from a slide
This change adds support for adding objects at run-time in the new animation system. Note that this is now done in-place and requires no rebuilding of the animation track for the slide, which means objects with animations will start immediately at the right place. Change-Id: I987aa1aeaa272f3506310304b5543bd6f9547d39 Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
-rw-r--r--src/runtime/q3dsuippresentation_p.h5
-rw-r--r--src/runtime/slideplayerng/q3dsanimationmanagerng.cpp87
-rw-r--r--src/runtime/slideplayerng/q3dsanimationmanagerng_p.h2
-rw-r--r--src/runtime/slideplayerng/q3dsslideplayerng.cpp6
-rw-r--r--tests/manual/standalone/main.cpp11
5 files changed, 85 insertions, 26 deletions
diff --git a/src/runtime/q3dsuippresentation_p.h b/src/runtime/q3dsuippresentation_p.h
index e87a192..2e89a22 100644
--- a/src/runtime/q3dsuippresentation_p.h
+++ b/src/runtime/q3dsuippresentation_p.h
@@ -668,6 +668,7 @@ public:
Q_ENUM(PlayThrough)
using PropertyChanges = QHash<Q3DSGraphObject *, Q3DSPropertyChangeList *>;
+ using AnimationTrackList = QVector<Q3DSAnimationTrack>;
Q3DSSlide();
~Q3DSSlide();
@@ -685,7 +686,7 @@ public:
void removePropertyChanges(Q3DSGraphObject *target);
Q3DSPropertyChangeList *takePropertyChanges(Q3DSGraphObject *target);
- const QVector<Q3DSAnimationTrack> &animations() const { return m_anims; }
+ const AnimationTrackList &animations() const { return m_anims; }
void addAnimation(const Q3DSAnimationTrack &track);
void removeAnimation(const Q3DSAnimationTrack &track);
@@ -750,7 +751,7 @@ private:
QVariant m_playThroughValue;
QSet<Q3DSGraphObject *> m_objects;
PropertyChanges m_propChanges;
- QVector<Q3DSAnimationTrack> m_anims;
+ AnimationTrackList m_anims;
QVector<Q3DSAction> m_actions;
QVector<SlideGraphChangeCallback> m_slideGraphChangeCallbacks; // master only
QVector<SlideObjectChangeCallback> m_slideObjectChangeCallbacks;
diff --git a/src/runtime/slideplayerng/q3dsanimationmanagerng.cpp b/src/runtime/slideplayerng/q3dsanimationmanagerng.cpp
index 116cb0d..815ae48 100644
--- a/src/runtime/slideplayerng/q3dsanimationmanagerng.cpp
+++ b/src/runtime/slideplayerng/q3dsanimationmanagerng.cpp
@@ -126,24 +126,9 @@ static void addKeyFramesForTrack(const Q3DSAnimationTrack &track, Q3DSAnimator::
}
}
-void Q3DSAnimationManagerNg::buildSlideAnimation(Q3DSSlide *slide, bool rebuild)
+static void buildAnimationData(const Q3DSSlide::AnimationTrackList &tracks,
+ Q3DSAnimator::AnimationDataList *animationDataList)
{
- if (!slide)
- return;
-
- Q3DSSlideAttached *data = slide->attached<Q3DSSlideAttached>();
- Q_ASSERT(data);
- if (!data->animatorNg)
- data->animatorNg = new Q3DSAnimator;
-
- if (!rebuild && !data->animatorNg->animationDataList.isEmpty())
- return;
-
- auto &animationDataList = data->animatorNg->animationDataList;
- animationDataList.clear();
-
- // NOTE: the assumption here is that tracks are ordered as, e.g., rotation.x, rotation.y...
- const auto &tracks = slide->animations();
auto cit = tracks.cbegin();
const auto cend = tracks.cend();
while (cit != cend) {
@@ -159,10 +144,10 @@ void Q3DSAnimationManagerNg::buildSlideAnimation(Q3DSSlide *slide, bool rebuild)
component.componentData.component = comp;
component.componentData.size = quint16(track.keyFrames().size());
component.componentData.dynamic = track.isDynamic();
- animationDataList.push_back(component);
+ animationDataList->push_back(component);
// 2. Add key frames for component track
- addKeyFramesForTrack(track, &animationDataList);
+ addKeyFramesForTrack(track, animationDataList);
// 3. Add the target data (if we're at end, the target changes, or the property changes
if ((cit + 1) == cend || (cit->target() != (cit + 1)->target() || !(cit + 1)->property().startsWith(prop[0]))) {
@@ -178,12 +163,33 @@ void Q3DSAnimationManagerNg::buildSlideAnimation(Q3DSSlide *slide, bool rebuild)
const auto type = Q3DSGraphObject::readProperty(track.target(), pid).type();
Q_ASSERT(type != QVariant::Invalid);
targetData.targetData.type = type;
- animationDataList.push_back(targetData);
+ animationDataList->push_back(targetData);
}
++cit;
}
}
+void Q3DSAnimationManagerNg::buildSlideAnimation(Q3DSSlide *slide, bool rebuild)
+{
+ if (!slide)
+ return;
+
+ Q3DSSlideAttached *data = slide->attached<Q3DSSlideAttached>();
+ Q_ASSERT(data);
+ if (!data->animatorNg)
+ data->animatorNg = new Q3DSAnimator;
+
+ if (!rebuild && !data->animatorNg->animationDataList.isEmpty())
+ return;
+
+ auto &animationDataList = data->animatorNg->animationDataList;
+ animationDataList.clear();
+
+ // NOTE: the assumption here is that tracks are ordered as, e.g., rotation.x, rotation.y...
+ const auto &tracks = slide->animations();
+ buildAnimationData(tracks, &animationDataList);
+}
+
void Q3DSAnimationManagerNg::updateDynamicKeyFrames(Q3DSSlide *slide)
{
if (!slide)
@@ -281,4 +287,45 @@ void Q3DSAnimationManagerNg::advance(Q3DSSlide *slide, float dtMs)
slide->attached<Q3DSSlideAttached>()->animatorNg->advance(dtMs / 1000.f);
}
+void Q3DSAnimationManagerNg::addObject(Q3DSSlide *slide, Q3DSGraphObject *obj)
+{
+ if (slide && slide->attached<Q3DSSlideAttached>()->animatorNg) {
+ auto &animationDataList = slide->attached<Q3DSSlideAttached>()->animatorNg->animationDataList;
+ const auto tracks = slide->animations();
+ Q3DSSlide::AnimationTrackList tracksForObject;
+ auto cit = tracks.cbegin();
+ while (cit != tracks.cend()) {
+ if (cit->target() == obj)
+ tracksForObject.push_back(*cit);
+ ++cit;
+ }
+ buildAnimationData(tracksForObject, &animationDataList);
+ }
+}
+
+void Q3DSAnimationManagerNg::removeObject(Q3DSSlide *slide, Q3DSGraphObject *obj)
+{
+ if (slide && slide->attached<Q3DSSlideAttached>()->animatorNg) {
+ Q3DSAnimator *animator = slide->attached<Q3DSSlideAttached>()->animatorNg;
+ auto &dl = animator->animationDataList;
+
+ auto it = dl.begin();
+ const auto end = dl.end();
+ auto removeStart = it;
+ while (it != end) {
+ if (it->type == Q3DSAnimationData::DataType::Target) {
+ if (it->targetData.target == obj)
+ break;
+ removeStart = it + 1;
+ Q_ASSERT(removeStart == end || removeStart->type == Q3DSAnimationData::DataType::Component);
+ }
+ ++it;
+ }
+
+ if (it != end) {
+ Q_ASSERT(removeStart->type == Q3DSAnimationData::DataType::Component && it->type == Q3DSAnimationData::DataType::Target);
+ dl.erase(removeStart, it + 1);
+ }
+ }
+}
QT_END_NAMESPACE
diff --git a/src/runtime/slideplayerng/q3dsanimationmanagerng_p.h b/src/runtime/slideplayerng/q3dsanimationmanagerng_p.h
index 0621f9b..389877c 100644
--- a/src/runtime/slideplayerng/q3dsanimationmanagerng_p.h
+++ b/src/runtime/slideplayerng/q3dsanimationmanagerng_p.h
@@ -58,6 +58,8 @@ namespace Q3DSAnimationManagerNg
Q3DSV_PRIVATE_EXPORT void setTimeChangeCallback(Q3DSSlide *slide, Q3DSAnimator::TimeChangeCallback cb);
Q3DSV_PRIVATE_EXPORT void buildSlideAnimation(Q3DSSlide *slide, bool rebuild = false);
Q3DSV_PRIVATE_EXPORT void updateDynamicKeyFrames(Q3DSSlide *slide);
+ Q3DSV_PRIVATE_EXPORT void addObject(Q3DSSlide *slide, Q3DSGraphObject *obj);
+ Q3DSV_PRIVATE_EXPORT void removeObject(Q3DSSlide *slide, Q3DSGraphObject *obj);
};
QT_END_NAMESPACE
diff --git a/src/runtime/slideplayerng/q3dsslideplayerng.cpp b/src/runtime/slideplayerng/q3dsslideplayerng.cpp
index 8e217b3..293701d 100644
--- a/src/runtime/slideplayerng/q3dsslideplayerng.cpp
+++ b/src/runtime/slideplayerng/q3dsslideplayerng.cpp
@@ -879,21 +879,21 @@ void Q3DSSlidePlayerNg::objectAboutToBeAddedToScene(Q3DSGraphObject *obj)
void Q3DSSlidePlayerNg::objectAboutToBeRemovedFromScene(Q3DSGraphObject *obj)
{
- // TODO:
- (void)obj;
-// m_animationManager->objectAboutToBeRemovedFromScene(obj);
+ evaluateDynamicObjectVisibility(obj);
}
void Q3DSSlidePlayerNg::objectAddedToSlide(Q3DSGraphObject *obj, Q3DSSlide *slide)
{
qDebug(lcSlidePlayer) << "Dyn.added object" << obj->id() << "to slide" << slide->id();
evaluateDynamicObjectVisibility(obj);
+ Q3DSAnimationManagerNg::addObject(slide, obj);
}
void Q3DSSlidePlayerNg::objectRemovedFromSlide(Q3DSGraphObject *obj, Q3DSSlide *slide)
{
qDebug(lcSlidePlayer) << "Dyn.removed object" << obj->id() << "from slide" << slide->id();
evaluateDynamicObjectVisibility(obj);
+ Q3DSAnimationManagerNg::removeObject(slide, obj);
}
QT_END_NAMESPACE
diff --git a/tests/manual/standalone/main.cpp b/tests/manual/standalone/main.cpp
index c8d207b..2fe598f 100644
--- a/tests/manual/standalone/main.cpp
+++ b/tests/manual/standalone/main.cpp
@@ -53,9 +53,13 @@ void buildDynamicSpawner(Q3DSUipPresentation *pres, Q3DSLayerNode *layer, Q3DSSl
++dyncounter;
newmodel->appendChildNode(newmat);
- newmodel->setMesh(QLatin1String("#Sphere"));
+ newmodel->setMesh(QLatin1String("#Cone"));
newmodel->setPosition(QVector3D((qrand() % 600) - 300, (qrand() % 600) - 300, 0));
+ Q3DSAnimationTrack anim(Q3DSAnimationTrack::Linear, newmodel, QLatin1String("rotation.y"));
+ anim.setKeyFrames({ { 0, 0 }, { 1, 45 }, { 2, 0 }, { 3, -45 }, { 4, 0 }, { 5, 45 }, { 6, 0 }, { 7, -45 }, { 8, 0 } });
+ slide->addAnimation(anim);
+
slide->addObject(newmodel);
slide->addObject(newmat);
@@ -222,9 +226,14 @@ Q3DSUipPresentation *build()
Q3DSSlide *masterSlide = mainPres->newObject<Q3DSSlide>("master");
Q3DSSlide *slide1 = mainPres->newObject<Q3DSSlide>("slide1");
slide1->setName(QLatin1String("Slide 1"));
+ slide1->setPlayMode(Q3DSSlide::PlayThroughTo);
+ slide1->setPlayThrough(Q3DSSlide::Next);
masterSlide->appendChildNode(slide1);
Q3DSSlide *slide2 = mainPres->newObject<Q3DSSlide>("slide2");
slide2->setName(QLatin1String("Slide 2"));
+ slide2->setPlayMode(Q3DSSlide::PlayThroughTo);
+ slide2->setPlayThrough(Q3DSSlide::Previous);
+ slide2->setEndTime(1000);
masterSlide->appendChildNode(slide2);
mainPres->setMasterSlide(masterSlide);