Made Animations safe for resource reload

This commit is contained in:
Atlante45 2015-07-10 12:01:51 -07:00
parent cfd5d72ff6
commit 6c591131ba
10 changed files with 31 additions and 22 deletions

View file

@ -53,7 +53,7 @@ AnimationDetails ScriptableAvatar::getAnimationDetails() {
void ScriptableAvatar::update(float deltatime) {
// Run animation
if (_animation != NULL && _animation->isValid() && _animation->getFrames().size() > 0) {
if (_animation && _animation->isLoaded() && _animation->getFrames().size() > 0) {
QStringList modelJoints = getJointNames();
QStringList animationJoints = _animation->getJointNames();

View file

@ -39,8 +39,7 @@ QSharedPointer<Resource> AnimationCache::createResource(const QUrl& url, const Q
}
Animation::Animation(const QUrl& url) :
Resource(url),
_isValid(false) {
Resource(url) {
}
class AnimationReader : public QRunnable {
@ -97,7 +96,6 @@ QVector<FBXAnimationFrame> Animation::getFrames() const {
void Animation::setGeometry(const FBXGeometry& geometry) {
_geometry = geometry;
finishedLoading(true);
_isValid = true;
}
void Animation::downloadFinished(QNetworkReply* reply) {

View file

@ -57,8 +57,6 @@ public:
Q_INVOKABLE QStringList getJointNames() const;
Q_INVOKABLE QVector<FBXAnimationFrame> getFrames() const;
bool isValid() const { return _isValid; }
protected:
@ -69,7 +67,6 @@ protected:
private:
FBXGeometry _geometry;
bool _isValid;
};

View file

@ -294,7 +294,7 @@ AudioInjector* AudioInjector::playSound(const QString& soundUrl, const float vol
if (soundCache.isNull()) {
return NULL;
}
SharedSoundPointer sound = soundCache.data()->getSound(QUrl(soundUrl));
SharedSoundPointer sound = soundCache->getSound(QUrl(soundUrl));
if (sound.isNull() || !sound->isReady()) {
return NULL;
}

View file

@ -184,7 +184,7 @@ void ModelEntityItem::cleanupLoadedAnimations() {
_loadedAnimations.clear();
}
Animation* ModelEntityItem::getAnimation(const QString& url) {
AnimationPointer ModelEntityItem::getAnimation(const QString& url) {
AnimationPointer animation;
// if we don't already have this model then create it and initialize it
@ -194,7 +194,7 @@ Animation* ModelEntityItem::getAnimation(const QString& url) {
} else {
animation = _loadedAnimations[url];
}
return animation.data();
return animation;
}
void ModelEntityItem::mapJoints(const QStringList& modelJointNames) {
@ -203,9 +203,8 @@ void ModelEntityItem::mapJoints(const QStringList& modelJointNames) {
return;
}
Animation* myAnimation = getAnimation(_animationURL);
if (!_jointMappingCompleted) {
AnimationPointer myAnimation = getAnimation(_animationURL);
if (myAnimation && myAnimation->isLoaded()) {
QStringList animationJointNames = myAnimation->getJointNames();
if (modelJointNames.size() > 0 && animationJointNames.size() > 0) {
@ -220,8 +219,12 @@ void ModelEntityItem::mapJoints(const QStringList& modelJointNames) {
QVector<glm::quat> ModelEntityItem::getAnimationFrame() {
QVector<glm::quat> frameData;
if (hasAnimation() && _jointMappingCompleted) {
Animation* myAnimation = getAnimation(_animationURL);
if (!hasAnimation() || !_jointMappingCompleted) {
return frameData;
}
AnimationPointer myAnimation = getAnimation(_animationURL);
if (myAnimation && myAnimation->isLoaded()) {
QVector<FBXAnimationFrame> frames = myAnimation->getFrames();
int frameCount = frames.size();
if (frameCount > 0) {

View file

@ -141,7 +141,7 @@ protected:
bool _jointMappingCompleted;
QVector<int> _jointMapping;
static Animation* getAnimation(const QString& url);
static AnimationPointer getAnimation(const QString& url);
static QMap<QString, AnimationPointer> _loadedAnimations;
static AnimationCache _animationCache;

View file

@ -271,11 +271,11 @@ void Resource::refresh() {
_replyTimer->deleteLater();
_replyTimer = nullptr;
}
init();
_request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork);
if (!_startedLoading) {
attemptRequest();
}
ensureLoading();
emit onRefresh();
}
void Resource::allReferencesCleared() {
@ -331,8 +331,7 @@ void Resource::reinsert() {
_cache->_resources.insert(_url, _self);
}
const int REPLY_TIMEOUT_MS = 5000;
static const int REPLY_TIMEOUT_MS = 5000;
void Resource::handleDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) {
if (!_reply->isFinished()) {
_bytesReceived = bytesReceived;

View file

@ -175,6 +175,7 @@ public:
signals:
/// Fired when the resource has been loaded.
void loaded();
void onRefresh();
protected slots:
void attemptRequest();

View file

@ -15,6 +15,7 @@
void AnimationHandle::setURL(const QUrl& url) {
if (_url != url) {
_animation = DependencyManager::get<AnimationCache>()->getAnimation(_url = url);
QObject::connect(_animation.data(), &Resource::onRefresh, this, &AnimationHandle::clearJoints);
_jointMappings.clear();
}
}
@ -110,11 +111,15 @@ void AnimationHandle::setAnimationDetails(const AnimationDetails& details) {
void AnimationHandle::simulate(float deltaTime) {
if (!_animation->isLoaded()) {
return;
}
_animationLoop.simulate(deltaTime);
// update the joint mappings if necessary/possible
if (_jointMappings.isEmpty()) {
if (_model->isActive()) {
if (_model && _model->isActive()) {
_jointMappings = _model->getGeometry()->getJointMappings(_animation);
}
if (_jointMappings.isEmpty()) {
@ -146,6 +151,10 @@ void AnimationHandle::simulate(float deltaTime) {
}
void AnimationHandle::applyFrame(float frameIndex) {
if (!_animation->isLoaded()) {
return;
}
const FBXGeometry& animationGeometry = _animation->getGeometry();
int frameCount = animationGeometry.animationFrames.size();
const FBXAnimationFrame& floorFrame = animationGeometry.animationFrames.at((int)glm::floor(frameIndex) % frameCount);

View file

@ -94,6 +94,8 @@ private:
void replaceMatchingPriorities(float newPriority);
void restoreJoints();
void clearJoints() { _jointMappings.clear(); }
Model* _model;
WeakAnimationHandlePointer _self;
AnimationPointer _animation;