Merge pull request #5634 from hyperlogic/tony/animation-resource-fix

Fix for animation resources
This commit is contained in:
Howard Stearns 2015-08-24 08:13:33 -07:00
commit bb91b17314
5 changed files with 69 additions and 39 deletions

View file

@ -8,6 +8,8 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
var HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
var toolIconUrl = HIFI_PUBLIC_BUCKET + "images/tools/";
progressDialog = (function () {
var that = {},
@ -142,4 +144,4 @@ progressDialog = (function () {
that.cleanup = cleanup;
return that;
}());
}());

View file

@ -39,35 +39,43 @@ QSharedPointer<Resource> AnimationCache::createResource(const QUrl& url, const Q
return QSharedPointer<Resource>(new Animation(url), &Resource::allReferencesCleared);
}
Animation::Animation(const QUrl& url) : Resource(url) {}
class AnimationReader : public QRunnable {
public:
AnimationReader(const QWeakPointer<Resource>& animation, QNetworkReply* reply);
virtual void run();
private:
QWeakPointer<Resource> _animation;
QNetworkReply* _reply;
};
AnimationReader::AnimationReader(const QWeakPointer<Resource>& animation, QNetworkReply* reply) :
_animation(animation),
AnimationReader::AnimationReader(const QUrl& url, QNetworkReply* reply) :
_url(url),
_reply(reply) {
}
void AnimationReader::run() {
QSharedPointer<Resource> animation = _animation.toStrongRef();
if (!animation.isNull()) {
QMetaObject::invokeMethod(animation.data(), "setGeometry",
Q_ARG(FBXGeometry*, readFBX(_reply->readAll(), QVariantHash(), _reply->property("url").toString())));
try {
if (!_reply) {
throw QString("Reply is NULL ?!");
}
QString urlname = _url.path().toLower();
bool urlValid = true;
urlValid &= !urlname.isEmpty();
urlValid &= !_url.path().isEmpty();
if (urlValid) {
// Parse the FBX directly from the QNetworkReply
FBXGeometry* fbxgeo = nullptr;
if (_url.path().toLower().endsWith(".fbx")) {
fbxgeo = readFBX(_reply, QVariantHash(), _url.path());
} else {
QString errorStr("usupported format");
emit onError(299, errorStr);
}
emit onSuccess(fbxgeo);
} else {
throw QString("url is invalid");
}
} catch (const QString& error) {
emit onError(299, error);
}
_reply->deleteLater();
}
Animation::Animation(const QUrl& url) : Resource(url) {}
bool Animation::isLoaded() const {
return _loaded && _geometry;
}
@ -100,17 +108,27 @@ const QVector<FBXAnimationFrame>& Animation::getFramesReference() const {
return _geometry->animationFrames;
}
void Animation::setGeometry(FBXGeometry* geometry) {
void Animation::downloadFinished(QNetworkReply* reply) {
// parse the animation/fbx file on a background thread.
AnimationReader* animationReader = new AnimationReader(reply->url(), reply);
connect(animationReader, SIGNAL(onSuccess(FBXGeometry*)), SLOT(animationParseSuccess(FBXGeometry*)));
connect(animationReader, SIGNAL(onError(int, QString)), SLOT(animationParseError(int, QString)));
QThreadPool::globalInstance()->start(animationReader);
}
void Animation::animationParseSuccess(FBXGeometry* geometry) {
qCDebug(animation) << "Animation parse success" << _url.toDisplayString();
_geometry.reset(geometry);
finishedLoading(true);
}
void Animation::downloadFinished(QNetworkReply* reply) {
// send the reader off to the thread pool
QThreadPool::globalInstance()->start(new AnimationReader(_self, reply));
void Animation::animationParseError(int error, QString str) {
qCCritical(animation) << "Animation failure parsing " << _url.toDisplayString() << "code =" << error << str;
emit failed(QNetworkReply::UnknownContentError);
}
AnimationDetails::AnimationDetails() :
role(), url(), fps(0.0f), priority(0.0f), loop(false), hold(false),
startAutomatically(false), firstFrame(0.0f), lastFrame(0.0f), running(false), frameIndex(0.0f)

View file

@ -12,6 +12,7 @@
#ifndef hifi_AnimationCache_h
#define hifi_AnimationCache_h
#include <QRunnable>
#include <QScriptEngine>
#include <QScriptValue>
@ -64,16 +65,33 @@ public:
const QVector<FBXAnimationFrame>& getFramesReference() const;
protected:
Q_INVOKABLE void setGeometry(FBXGeometry* geometry);
virtual void downloadFinished(QNetworkReply* reply);
protected slots:
void animationParseSuccess(FBXGeometry* geometry);
void animationParseError(int error, QString str);
private:
std::unique_ptr<FBXGeometry> _geometry;
};
/// Reads geometry in a worker thread.
class AnimationReader : public QObject, public QRunnable {
Q_OBJECT
public:
AnimationReader(const QUrl& url, QNetworkReply* reply);
virtual void run();
signals:
void onSuccess(FBXGeometry* geometry);
void onError(int error, QString str);
private:
QUrl _url;
QNetworkReply* _reply;
};
class AnimationDetails {
public:

View file

@ -15,6 +15,7 @@
void AnimationHandle::setURL(const QUrl& url) {
if (_url != url) {
_animation = DependencyManager::get<AnimationCache>()->getAnimation(_url = url);
_animation->ensureLoading();
QObject::connect(_animation.data(), &Resource::onRefresh, this, &AnimationHandle::clearJoints);
_jointMappings.clear();
}

View file

@ -21,8 +21,6 @@
#include "FBXReader.h"
#include "OBJReader.h"
#include <AnimationCache.h>
#include <gpu/Batch.h>
#include <gpu/Stream.h>
@ -383,20 +381,13 @@ protected:
/// Reads geometry in a worker thread.
class GeometryReader : public QObject, public QRunnable {
Q_OBJECT
public:
GeometryReader(const QUrl& url, QNetworkReply* reply, const QVariantHash& mapping);
virtual void run();
signals:
void onSuccess(FBXGeometry* geometry);
void onError(int error, QString str);
private:
QWeakPointer<Resource> _geometry;
QUrl _url;
QNetworkReply* _reply;
QVariantHash _mapping;