mirror of
https://github.com/overte-org/overte.git
synced 2025-04-10 19:29:07 +02:00
Fix for animation resources
The problem was that the invokeMethod between the AnimationReader thread and the main thread was failing, because FBXGeometry* wasn't a registered meta type. So, I ended up normalizing the AnimationReader class to be more like GeometryReader, in that it uses singles and slots to communicate success and failure, rather then invokeMethod.
This commit is contained in:
parent
0fb2390877
commit
b7009b4631
6 changed files with 77 additions and 40 deletions
|
@ -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;
|
||||
}());
|
||||
}());
|
||||
|
|
|
@ -39,35 +39,44 @@ 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();
|
||||
urlValid &= _url.path().toLower().endsWith(".fbx");
|
||||
|
||||
if (urlValid) {
|
||||
// Let's read the binaries from the network
|
||||
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 +109,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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -182,7 +182,7 @@ QString FBXGeometry::getModelNameOfMesh(int meshIndex) const {
|
|||
|
||||
static int fbxGeometryMetaTypeId = qRegisterMetaType<FBXGeometry>();
|
||||
static int fbxAnimationFrameMetaTypeId = qRegisterMetaType<FBXAnimationFrame>();
|
||||
static int fbxAnimationFrameVectorMetaTypeId = qRegisterMetaType<QVector<FBXAnimationFrame> >();
|
||||
static int fbxAnimationFrameVectorMetaTypeId = qRegisterMetaType<QVector<FBXAnimationFrame>>();
|
||||
|
||||
template<class T> int streamSize() {
|
||||
return sizeof(T);
|
||||
|
@ -1858,12 +1858,18 @@ FBXGeometry* extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping
|
|||
foreach (const FBXNode& subobject, object.children) {
|
||||
if (subobject.name == "RelativeFilename") {
|
||||
QByteArray filename = subobject.properties.at(0).toByteArray();
|
||||
qCDebug(modelformat) << "AJT: RelativeFilename, filename =" << filename;
|
||||
filename = fileOnUrl(filename, url);
|
||||
qCDebug(modelformat) << "AJT: url = " << url;
|
||||
qCDebug(modelformat) << "AJT: filename2 = " << filename;
|
||||
|
||||
textureFilenames.insert(getID(object.properties), filename);
|
||||
} else if (subobject.name == "TextureName") {
|
||||
// trim the name from the timestamp
|
||||
QString name = QString(subobject.properties.at(0).toByteArray());
|
||||
qCDebug(modelformat) << "AJT: TextureName, name =" << name;
|
||||
name = name.left(name.indexOf('['));
|
||||
qCDebug(modelformat) << "AJT: name2 =" << name;
|
||||
textureNames.insert(getID(object.properties), name);
|
||||
} else if (subobject.name == "Texture_Alpha_Source") {
|
||||
tex.assign<uint8_t>(tex.alphaSource, subobject.properties.at(0).value<int>());
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue