diff --git a/libraries/animation/src/AnimationCache.h b/libraries/animation/src/AnimationCache.h index ca5ea5b072..483350e2b5 100644 --- a/libraries/animation/src/AnimationCache.h +++ b/libraries/animation/src/AnimationCache.h @@ -22,7 +22,7 @@ class Animation; -typedef QSharedPointer AnimationPointer; +using AnimationPointer = QSharedPointer; class AnimationCache : public ResourceCache, public Dependency { Q_OBJECT diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 0452587439..c6337dc872 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -975,14 +975,21 @@ QStringList RenderableModelEntityItem::getJointNames() const { return result; } -// FIXME: deprecated; remove >= RC67 -bool RenderableModelEntityItem::getMeshes(MeshProxyList& result) { - auto model = getModel(); - if (!model || !model->isLoaded()) { - return false; +void RenderableModelEntityItem::setAnimationURL(const QString& url) { + QString oldURL = getAnimationURL(); + ModelEntityItem::setAnimationURL(url); + if (oldURL != getAnimationURL()) { + _needsAnimationReset = true; } - BLOCKING_INVOKE_METHOD(model.get(), "getMeshes", Q_RETURN_ARG(MeshProxyList, result)); - return !result.isEmpty(); +} + +bool RenderableModelEntityItem::needsAnimationReset() const { + return _needsAnimationReset; +} + +QString RenderableModelEntityItem::getAnimationURLAndReset() { + _needsAnimationReset = false; + return getAnimationURL(); } scriptable::ScriptableModelBase render::entities::ModelEntityRenderer::getScriptableModel() { @@ -1068,6 +1075,13 @@ void RenderableModelEntityItem::copyAnimationJointDataToModel() { } } +bool RenderableModelEntityItem::readyToAnimate() const { + return resultWithReadLock([&] { + float firstFrame = _animationProperties.getFirstFrame(); + return (firstFrame >= 0.0f) && (firstFrame <= _animationProperties.getLastFrame()); + }); +} + using namespace render; using namespace render::entities; @@ -1155,7 +1169,7 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) { const QVector& rotations = frames[_lastKnownCurrentFrame].rotations; const QVector& translations = frames[_lastKnownCurrentFrame].translations; - + jointsData.resize(_jointMapping.size()); for (int j = 0; j < _jointMapping.size(); j++) { int index = _jointMapping[j]; @@ -1169,13 +1183,12 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) { } } else if (index < animationJointNames.size()) { QString jointName = fbxJoints[index].name; // Pushing this here so its not done on every entity, with the exceptions of those allowing for translation - if (originalFbxIndices.contains(jointName)) { // Making sure the joint names exist in the original model the animation is trying to apply onto. If they do, then remap and get it's translation. int remappedIndex = originalFbxIndices[jointName] - 1; // JointIndeces seem to always start from 1 and the found index is always 1 higher than actual. translationMat = glm::translate(originalFbxJoints[remappedIndex].translation); } - } + } glm::mat4 rotationMat; if (index < rotations.size()) { rotationMat = glm::mat4_cast(fbxJoints[index].preRotation * rotations[index] * fbxJoints[index].postRotation); @@ -1477,14 +1490,17 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce if (_animating) { DETAILED_PROFILE_RANGE(simulation_physics, "Animate"); - if (!jointsMapped()) { - mapJoints(entity, model->getJointNames()); - //else the joint have been mapped before but we have a new animation to load - } else if (_animation && (_animation->getURL().toString() != entity->getAnimationURL())) { + if (_animation && entity->needsAnimationReset()) { + //(_animation->getURL().toString() != entity->getAnimationURL())) { // bad check + // the joints have been mapped before but we have a new animation to load + _animation.reset(); _jointMappingCompleted = false; - mapJoints(entity, model->getJointNames()); } - if (!(entity->getAnimationFirstFrame() < 0) && !(entity->getAnimationFirstFrame() > entity->getAnimationLastFrame())) { + + if (!_jointMappingCompleted) { + mapJoints(entity, model); + } + if (entity->readyToAnimate()) { animate(entity); } emit requestRenderUpdate(); @@ -1518,19 +1534,20 @@ void ModelEntityRenderer::doRender(RenderArgs* args) { #endif } -void ModelEntityRenderer::mapJoints(const TypedEntityPointer& entity, const QStringList& modelJointNames) { +void ModelEntityRenderer::mapJoints(const TypedEntityPointer& entity, const ModelPointer& model) { // if we don't have animation, or we're already joint mapped then bail early - if (!entity->hasAnimation() || jointsMapped()) { + if (!entity->hasAnimation()) { return; } - if (!_animation || _animation->getURL().toString() != entity->getAnimationURL()) { - _animation = DependencyManager::get()->getAnimation(entity->getAnimationURL()); + if (!_animation) { + _animation = DependencyManager::get()->getAnimation(entity->getAnimationURLAndReset()); } if (_animation && _animation->isLoaded()) { QStringList animationJointNames = _animation->getJointNames(); + auto modelJointNames = model->getJointNames(); if (modelJointNames.size() > 0 && animationJointNames.size() > 0) { _jointMapping.resize(modelJointNames.size()); for (int i = 0; i < modelJointNames.size(); i++) { diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 2d31549872..79e56d7a76 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -112,21 +112,25 @@ public: virtual int getJointIndex(const QString& name) const override; virtual QStringList getJointNames() const override; - bool getMeshes(MeshProxyList& result) override; // deprecated + void setAnimationURL(const QString& url) override; + bool needsAnimationReset() const; + QString getAnimationURLAndReset(); private: bool needsUpdateModelBounds() const; void autoResizeJointArrays(); void copyAnimationJointDataToModel(); - + bool readyToAnimate() const; void getCollisionGeometryResource(); + GeometryResource::Pointer _compoundShapeResource; - bool _jointMapCompleted { false }; - bool _originalTexturesRead { false }; std::vector _jointMap; QVariantMap _originalTextures; + bool _jointMapCompleted { false }; + bool _originalTexturesRead { false }; bool _dimensionsInitialized { true }; bool _needsJointSimulation { false }; + bool _needsAnimationReset { false }; }; namespace render { namespace entities { @@ -167,8 +171,7 @@ protected: private: void animate(const TypedEntityPointer& entity); - void mapJoints(const TypedEntityPointer& entity, const QStringList& modelJointNames); - bool jointsMapped() const { return _jointMappingCompleted; } + void mapJoints(const TypedEntityPointer& entity, const ModelPointer& model); // Transparency is handled in ModelMeshPartPayload virtual bool isTransparent() const override { return false; } diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 72192c8702..b4b00e57a7 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -629,30 +629,6 @@ bool ModelEntityItem::getAnimationHold() const { }); } -void ModelEntityItem::setAnimationFirstFrame(float firstFrame) { - withWriteLock([&] { - _animationProperties.setFirstFrame(firstFrame); - }); -} - -float ModelEntityItem::getAnimationFirstFrame() const { - return resultWithReadLock([&] { - return _animationProperties.getFirstFrame(); - }); -} - -void ModelEntityItem::setAnimationLastFrame(float lastFrame) { - withWriteLock([&] { - _animationProperties.setLastFrame(lastFrame); - }); -} - -float ModelEntityItem::getAnimationLastFrame() const { - return resultWithReadLock([&] { - return _animationProperties.getLastFrame(); - }); -} - bool ModelEntityItem::getAnimationIsPlaying() const { return resultWithReadLock([&] { return _animationProperties.getRunning(); diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index 91d2d81b88..5ca3e2caa1 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -79,9 +79,10 @@ public: // Animation related items... AnimationPropertyGroup getAnimationProperties() const; + // TODO: audit and remove unused Animation accessors bool hasAnimation() const; QString getAnimationURL() const; - void setAnimationURL(const QString& url); + virtual void setAnimationURL(const QString& url); void setAnimationCurrentFrame(float value); void setAnimationIsPlaying(bool value); @@ -99,12 +100,6 @@ public: void setRelayParentJoints(bool relayJoints); bool getRelayParentJoints() const; - void setAnimationFirstFrame(float firstFrame); - float getAnimationFirstFrame() const; - - void setAnimationLastFrame(float lastFrame); - float getAnimationLastFrame() const; - bool getAnimationIsPlaying() const; float getAnimationCurrentFrame() const; float getAnimationFPS() const;