mirror of
https://github.com/overte-org/overte.git
synced 2025-07-23 12:44:03 +02:00
Merge pull request #13979 from AndrewMeadows/game-loop-optimizations-001
minor bug fix and optimization in ModelEntity animation
This commit is contained in:
commit
6005b934ad
5 changed files with 49 additions and 58 deletions
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
class Animation;
|
class Animation;
|
||||||
|
|
||||||
typedef QSharedPointer<Animation> AnimationPointer;
|
using AnimationPointer = QSharedPointer<Animation>;
|
||||||
|
|
||||||
class AnimationCache : public ResourceCache, public Dependency {
|
class AnimationCache : public ResourceCache, public Dependency {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
|
@ -975,14 +975,21 @@ QStringList RenderableModelEntityItem::getJointNames() const {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: deprecated; remove >= RC67
|
void RenderableModelEntityItem::setAnimationURL(const QString& url) {
|
||||||
bool RenderableModelEntityItem::getMeshes(MeshProxyList& result) {
|
QString oldURL = getAnimationURL();
|
||||||
auto model = getModel();
|
ModelEntityItem::setAnimationURL(url);
|
||||||
if (!model || !model->isLoaded()) {
|
if (oldURL != getAnimationURL()) {
|
||||||
return false;
|
_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() {
|
scriptable::ScriptableModelBase render::entities::ModelEntityRenderer::getScriptableModel() {
|
||||||
|
@ -1068,6 +1075,13 @@ void RenderableModelEntityItem::copyAnimationJointDataToModel() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RenderableModelEntityItem::readyToAnimate() const {
|
||||||
|
return resultWithReadLock<bool>([&] {
|
||||||
|
float firstFrame = _animationProperties.getFirstFrame();
|
||||||
|
return (firstFrame >= 0.0f) && (firstFrame <= _animationProperties.getLastFrame());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
using namespace render;
|
using namespace render;
|
||||||
using namespace render::entities;
|
using namespace render::entities;
|
||||||
|
|
||||||
|
@ -1169,7 +1183,6 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) {
|
||||||
}
|
}
|
||||||
} else if (index < animationJointNames.size()) {
|
} 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
|
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)) {
|
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.
|
// 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.
|
int remappedIndex = originalFbxIndices[jointName] - 1; // JointIndeces seem to always start from 1 and the found index is always 1 higher than actual.
|
||||||
|
@ -1477,14 +1490,17 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
|
||||||
if (_animating) {
|
if (_animating) {
|
||||||
DETAILED_PROFILE_RANGE(simulation_physics, "Animate");
|
DETAILED_PROFILE_RANGE(simulation_physics, "Animate");
|
||||||
|
|
||||||
if (!jointsMapped()) {
|
if (_animation && entity->needsAnimationReset()) {
|
||||||
mapJoints(entity, model->getJointNames());
|
//(_animation->getURL().toString() != entity->getAnimationURL())) { // bad check
|
||||||
//else the joint have been mapped before but we have a new animation to load
|
// the joints have been mapped before but we have a new animation to load
|
||||||
} else if (_animation && (_animation->getURL().toString() != entity->getAnimationURL())) {
|
_animation.reset();
|
||||||
_jointMappingCompleted = false;
|
_jointMappingCompleted = false;
|
||||||
mapJoints(entity, model->getJointNames());
|
|
||||||
}
|
}
|
||||||
if (!(entity->getAnimationFirstFrame() < 0) && !(entity->getAnimationFirstFrame() > entity->getAnimationLastFrame())) {
|
|
||||||
|
if (!_jointMappingCompleted) {
|
||||||
|
mapJoints(entity, model);
|
||||||
|
}
|
||||||
|
if (entity->readyToAnimate()) {
|
||||||
animate(entity);
|
animate(entity);
|
||||||
}
|
}
|
||||||
emit requestRenderUpdate();
|
emit requestRenderUpdate();
|
||||||
|
@ -1518,19 +1534,20 @@ void ModelEntityRenderer::doRender(RenderArgs* args) {
|
||||||
#endif
|
#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 we don't have animation, or we're already joint mapped then bail early
|
||||||
if (!entity->hasAnimation() || jointsMapped()) {
|
if (!entity->hasAnimation()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_animation || _animation->getURL().toString() != entity->getAnimationURL()) {
|
if (!_animation) {
|
||||||
_animation = DependencyManager::get<AnimationCache>()->getAnimation(entity->getAnimationURL());
|
_animation = DependencyManager::get<AnimationCache>()->getAnimation(entity->getAnimationURLAndReset());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_animation && _animation->isLoaded()) {
|
if (_animation && _animation->isLoaded()) {
|
||||||
QStringList animationJointNames = _animation->getJointNames();
|
QStringList animationJointNames = _animation->getJointNames();
|
||||||
|
|
||||||
|
auto modelJointNames = model->getJointNames();
|
||||||
if (modelJointNames.size() > 0 && animationJointNames.size() > 0) {
|
if (modelJointNames.size() > 0 && animationJointNames.size() > 0) {
|
||||||
_jointMapping.resize(modelJointNames.size());
|
_jointMapping.resize(modelJointNames.size());
|
||||||
for (int i = 0; i < modelJointNames.size(); i++) {
|
for (int i = 0; i < modelJointNames.size(); i++) {
|
||||||
|
|
|
@ -112,21 +112,25 @@ public:
|
||||||
virtual int getJointIndex(const QString& name) const override;
|
virtual int getJointIndex(const QString& name) const override;
|
||||||
virtual QStringList getJointNames() 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:
|
private:
|
||||||
bool needsUpdateModelBounds() const;
|
bool needsUpdateModelBounds() const;
|
||||||
void autoResizeJointArrays();
|
void autoResizeJointArrays();
|
||||||
void copyAnimationJointDataToModel();
|
void copyAnimationJointDataToModel();
|
||||||
|
bool readyToAnimate() const;
|
||||||
void getCollisionGeometryResource();
|
void getCollisionGeometryResource();
|
||||||
|
|
||||||
GeometryResource::Pointer _compoundShapeResource;
|
GeometryResource::Pointer _compoundShapeResource;
|
||||||
bool _jointMapCompleted { false };
|
|
||||||
bool _originalTexturesRead { false };
|
|
||||||
std::vector<int> _jointMap;
|
std::vector<int> _jointMap;
|
||||||
QVariantMap _originalTextures;
|
QVariantMap _originalTextures;
|
||||||
|
bool _jointMapCompleted { false };
|
||||||
|
bool _originalTexturesRead { false };
|
||||||
bool _dimensionsInitialized { true };
|
bool _dimensionsInitialized { true };
|
||||||
bool _needsJointSimulation { false };
|
bool _needsJointSimulation { false };
|
||||||
|
bool _needsAnimationReset { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace render { namespace entities {
|
namespace render { namespace entities {
|
||||||
|
@ -167,8 +171,7 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void animate(const TypedEntityPointer& entity);
|
void animate(const TypedEntityPointer& entity);
|
||||||
void mapJoints(const TypedEntityPointer& entity, const QStringList& modelJointNames);
|
void mapJoints(const TypedEntityPointer& entity, const ModelPointer& model);
|
||||||
bool jointsMapped() const { return _jointMappingCompleted; }
|
|
||||||
|
|
||||||
// Transparency is handled in ModelMeshPartPayload
|
// Transparency is handled in ModelMeshPartPayload
|
||||||
virtual bool isTransparent() const override { return false; }
|
virtual bool isTransparent() const override { return false; }
|
||||||
|
|
|
@ -629,30 +629,6 @@ bool ModelEntityItem::getAnimationHold() const {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelEntityItem::setAnimationFirstFrame(float firstFrame) {
|
|
||||||
withWriteLock([&] {
|
|
||||||
_animationProperties.setFirstFrame(firstFrame);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
float ModelEntityItem::getAnimationFirstFrame() const {
|
|
||||||
return resultWithReadLock<float>([&] {
|
|
||||||
return _animationProperties.getFirstFrame();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void ModelEntityItem::setAnimationLastFrame(float lastFrame) {
|
|
||||||
withWriteLock([&] {
|
|
||||||
_animationProperties.setLastFrame(lastFrame);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
float ModelEntityItem::getAnimationLastFrame() const {
|
|
||||||
return resultWithReadLock<float>([&] {
|
|
||||||
return _animationProperties.getLastFrame();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ModelEntityItem::getAnimationIsPlaying() const {
|
bool ModelEntityItem::getAnimationIsPlaying() const {
|
||||||
return resultWithReadLock<bool>([&] {
|
return resultWithReadLock<bool>([&] {
|
||||||
return _animationProperties.getRunning();
|
return _animationProperties.getRunning();
|
||||||
|
|
|
@ -79,9 +79,10 @@ public:
|
||||||
// Animation related items...
|
// Animation related items...
|
||||||
AnimationPropertyGroup getAnimationProperties() const;
|
AnimationPropertyGroup getAnimationProperties() const;
|
||||||
|
|
||||||
|
// TODO: audit and remove unused Animation accessors
|
||||||
bool hasAnimation() const;
|
bool hasAnimation() const;
|
||||||
QString getAnimationURL() const;
|
QString getAnimationURL() const;
|
||||||
void setAnimationURL(const QString& url);
|
virtual void setAnimationURL(const QString& url);
|
||||||
|
|
||||||
void setAnimationCurrentFrame(float value);
|
void setAnimationCurrentFrame(float value);
|
||||||
void setAnimationIsPlaying(bool value);
|
void setAnimationIsPlaying(bool value);
|
||||||
|
@ -99,12 +100,6 @@ public:
|
||||||
void setRelayParentJoints(bool relayJoints);
|
void setRelayParentJoints(bool relayJoints);
|
||||||
bool getRelayParentJoints() const;
|
bool getRelayParentJoints() const;
|
||||||
|
|
||||||
void setAnimationFirstFrame(float firstFrame);
|
|
||||||
float getAnimationFirstFrame() const;
|
|
||||||
|
|
||||||
void setAnimationLastFrame(float lastFrame);
|
|
||||||
float getAnimationLastFrame() const;
|
|
||||||
|
|
||||||
bool getAnimationIsPlaying() const;
|
bool getAnimationIsPlaying() const;
|
||||||
float getAnimationCurrentFrame() const;
|
float getAnimationCurrentFrame() const;
|
||||||
float getAnimationFPS() const;
|
float getAnimationFPS() const;
|
||||||
|
|
Loading…
Reference in a new issue