mirror of
https://github.com/lubosz/overte.git
synced 2025-08-07 19:41:20 +02:00
Merge pull request #11804 from amantley/character_entity_fixes
Fixed Entity Animation Property not applying to FBXs
This commit is contained in:
commit
5087893097
7 changed files with 172 additions and 44 deletions
|
@ -402,6 +402,8 @@ void EntityTreeRenderer::update(bool simulate) {
|
||||||
PerformanceTimer perfTimer("ETRupdate");
|
PerformanceTimer perfTimer("ETRupdate");
|
||||||
if (_tree && !_shuttingDown) {
|
if (_tree && !_shuttingDown) {
|
||||||
EntityTreePointer tree = std::static_pointer_cast<EntityTree>(_tree);
|
EntityTreePointer tree = std::static_pointer_cast<EntityTree>(_tree);
|
||||||
|
|
||||||
|
// here we update _currentFrame and _lastAnimated and sync with the server properties.
|
||||||
tree->update(simulate);
|
tree->update(simulate);
|
||||||
|
|
||||||
// Update the rendereable entities as needed
|
// Update the rendereable entities as needed
|
||||||
|
@ -736,7 +738,7 @@ void EntityTreeRenderer::mouseReleaseEvent(QMouseEvent* event) {
|
||||||
PickRay ray = _viewState->computePickRay(event->x(), event->y());
|
PickRay ray = _viewState->computePickRay(event->x(), event->y());
|
||||||
RayToEntityIntersectionResult rayPickResult = _getPrevRayPickResultOperator(_mouseRayPickID);
|
RayToEntityIntersectionResult rayPickResult = _getPrevRayPickResultOperator(_mouseRayPickID);
|
||||||
if (rayPickResult.intersects && rayPickResult.entity) {
|
if (rayPickResult.intersects && rayPickResult.entity) {
|
||||||
//qCDebug(entitiesrenderer) << "mouseReleaseEvent over entity:" << rayPickResult.entityID;
|
// qCDebug(entitiesrenderer) << "mouseReleaseEvent over entity:" << rayPickResult.entityID;
|
||||||
|
|
||||||
glm::vec2 pos2D = projectOntoEntityXYPlane(rayPickResult.entity, ray, rayPickResult);
|
glm::vec2 pos2D = projectOntoEntityXYPlane(rayPickResult.entity, ray, rayPickResult);
|
||||||
PointerEvent pointerEvent(PointerEvent::Release, PointerManager::MOUSE_POINTER_ID,
|
PointerEvent pointerEvent(PointerEvent::Release, PointerManager::MOUSE_POINTER_ID,
|
||||||
|
|
|
@ -63,13 +63,17 @@ bool ModelEntityWrapper::isModelLoaded() const {
|
||||||
EntityItemPointer RenderableModelEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer RenderableModelEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
EntityItemPointer entity(new RenderableModelEntityItem(entityID, properties.getDimensionsInitialized()),
|
EntityItemPointer entity(new RenderableModelEntityItem(entityID, properties.getDimensionsInitialized()),
|
||||||
[](EntityItem* ptr) { ptr->deleteLater(); });
|
[](EntityItem* ptr) { ptr->deleteLater(); });
|
||||||
|
|
||||||
entity->setProperties(properties);
|
entity->setProperties(properties);
|
||||||
|
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderableModelEntityItem::RenderableModelEntityItem(const EntityItemID& entityItemID, bool dimensionsInitialized) :
|
RenderableModelEntityItem::RenderableModelEntityItem(const EntityItemID& entityItemID, bool dimensionsInitialized) :
|
||||||
ModelEntityWrapper(entityItemID),
|
ModelEntityWrapper(entityItemID),
|
||||||
_dimensionsInitialized(dimensionsInitialized) {
|
_dimensionsInitialized(dimensionsInitialized) {
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderableModelEntityItem::~RenderableModelEntityItem() { }
|
RenderableModelEntityItem::~RenderableModelEntityItem() { }
|
||||||
|
@ -464,7 +468,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
|
||||||
shapeInfo.setParams(type, dimensions, getCompoundShapeURL());
|
shapeInfo.setParams(type, dimensions, getCompoundShapeURL());
|
||||||
} else if (type >= SHAPE_TYPE_SIMPLE_HULL && type <= SHAPE_TYPE_STATIC_MESH) {
|
} else if (type >= SHAPE_TYPE_SIMPLE_HULL && type <= SHAPE_TYPE_STATIC_MESH) {
|
||||||
// TODO: assert we never fall in here when model not fully loaded
|
// TODO: assert we never fall in here when model not fully loaded
|
||||||
//assert(_model && _model->isLoaded());
|
// assert(_model && _model->isLoaded());
|
||||||
|
|
||||||
updateModelBounds();
|
updateModelBounds();
|
||||||
model->updateGeometry();
|
model->updateGeometry();
|
||||||
|
@ -974,9 +978,6 @@ void ModelEntityRenderer::onRemoveFromSceneTyped(const TypedEntityPointer& entit
|
||||||
entity->setModel({});
|
entity->setModel({});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const AnimationPropertyGroup& a, const AnimationPropertyGroup& b) {
|
|
||||||
return !(a == b);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ModelEntityRenderer::animate(const TypedEntityPointer& entity) {
|
void ModelEntityRenderer::animate(const TypedEntityPointer& entity) {
|
||||||
if (!_animation || !_animation->isLoaded()) {
|
if (!_animation || !_animation->isLoaded()) {
|
||||||
|
@ -991,19 +992,12 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_lastAnimated) {
|
|
||||||
_lastAnimated = usecTimestampNow();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto now = usecTimestampNow();
|
|
||||||
auto interval = now - _lastAnimated;
|
|
||||||
_lastAnimated = now;
|
|
||||||
float deltaTime = (float)interval / (float)USECS_PER_SECOND;
|
|
||||||
_currentFrame += (deltaTime * _renderAnimationProperties.getFPS());
|
|
||||||
|
|
||||||
{
|
{
|
||||||
int animationCurrentFrame = (int)(glm::floor(_currentFrame)) % frameCount;
|
// the current frame is set on the server in update() in ModelEntityItem.cpp
|
||||||
|
int animationCurrentFrame = (int)(glm::floor(entity->getAnimationCurrentFrame()));
|
||||||
|
|
||||||
|
// in the case where the last frame is greater than the framecount then clamp
|
||||||
|
// it to the end of the animation until it loops around.
|
||||||
if (animationCurrentFrame < 0 || animationCurrentFrame > frameCount) {
|
if (animationCurrentFrame < 0 || animationCurrentFrame > frameCount) {
|
||||||
animationCurrentFrame = 0;
|
animationCurrentFrame = 0;
|
||||||
}
|
}
|
||||||
|
@ -1039,10 +1033,10 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) {
|
||||||
glm::mat4 translationMat;
|
glm::mat4 translationMat;
|
||||||
|
|
||||||
if (allowTranslation) {
|
if (allowTranslation) {
|
||||||
if(index < translations.size()){
|
if (index < translations.size()) {
|
||||||
translationMat = glm::translate(translations[index]);
|
translationMat = glm::translate(translations[index]);
|
||||||
}
|
}
|
||||||
} 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)) {
|
||||||
|
@ -1317,25 +1311,17 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
|
||||||
if (model->getRenderItemsNeedUpdate()) {
|
if (model->getRenderItemsNeedUpdate()) {
|
||||||
model->updateRenderItems();
|
model->updateRenderItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
// The code to deal with the change of properties is now in ModelEntityItem.cpp
|
||||||
DETAILED_PROFILE_RANGE(simulation_physics, "CheckAnimation");
|
// That is where _currentFrame and _lastAnimated were updated.
|
||||||
// make a copy of the animation properites
|
|
||||||
auto newAnimationProperties = entity->getAnimationProperties();
|
|
||||||
if (newAnimationProperties != _renderAnimationProperties) {
|
|
||||||
withWriteLock([&] {
|
|
||||||
_renderAnimationProperties = newAnimationProperties;
|
|
||||||
_currentFrame = _renderAnimationProperties.getCurrentFrame();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_animating) {
|
if (_animating) {
|
||||||
DETAILED_PROFILE_RANGE(simulation_physics, "Animate");
|
DETAILED_PROFILE_RANGE(simulation_physics, "Animate");
|
||||||
if (!jointsMapped()) {
|
if (!jointsMapped()) {
|
||||||
mapJoints(entity, model->getJointNames());
|
mapJoints(entity, model->getJointNames());
|
||||||
}
|
}
|
||||||
animate(entity);
|
if (!(entity->getAnimationFirstFrame() < 0) && !(entity->getAnimationFirstFrame() > entity->getAnimationLastFrame())) {
|
||||||
|
animate(entity);
|
||||||
|
}
|
||||||
emit requestRenderUpdate();
|
emit requestRenderUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace render { namespace entities {
|
||||||
class ModelEntityRenderer;
|
class ModelEntityRenderer;
|
||||||
} }
|
} }
|
||||||
|
|
||||||
//#define MODEL_ENTITY_USE_FADE_EFFECT
|
// #define MODEL_ENTITY_USE_FADE_EFFECT
|
||||||
class ModelEntityWrapper : public ModelEntityItem {
|
class ModelEntityWrapper : public ModelEntityItem {
|
||||||
using Parent = ModelEntityItem;
|
using Parent = ModelEntityItem;
|
||||||
friend class render::entities::ModelEntityRenderer;
|
friend class render::entities::ModelEntityRenderer;
|
||||||
|
@ -133,7 +133,7 @@ class ModelEntityRenderer : public TypedEntityRenderer<RenderableModelEntityItem
|
||||||
friend class EntityRenderer;
|
friend class EntityRenderer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ModelEntityRenderer(const EntityItemPointer& entity) : Parent(entity) { }
|
ModelEntityRenderer(const EntityItemPointer& entity) : Parent(entity) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void removeFromScene(const ScenePointer& scene, Transaction& transaction) override;
|
virtual void removeFromScene(const ScenePointer& scene, Transaction& transaction) override;
|
||||||
|
@ -184,8 +184,6 @@ private:
|
||||||
bool _shouldHighlight { false };
|
bool _shouldHighlight { false };
|
||||||
bool _animating { false };
|
bool _animating { false };
|
||||||
uint64_t _lastAnimated { 0 };
|
uint64_t _lastAnimated { 0 };
|
||||||
float _currentFrame { 0 };
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} } // namespace
|
} } // namespace
|
||||||
|
|
|
@ -22,15 +22,28 @@ const float AnimationPropertyGroup::MAXIMUM_POSSIBLE_FRAME = 100000.0f;
|
||||||
|
|
||||||
bool operator==(const AnimationPropertyGroup& a, const AnimationPropertyGroup& b) {
|
bool operator==(const AnimationPropertyGroup& a, const AnimationPropertyGroup& b) {
|
||||||
return
|
return
|
||||||
(a._url == b._url) &&
|
|
||||||
(a._currentFrame == b._currentFrame) &&
|
(a._currentFrame == b._currentFrame) &&
|
||||||
(a._running == b._running) &&
|
(a._running == b._running) &&
|
||||||
(a._loop == b._loop) &&
|
(a._loop == b._loop) &&
|
||||||
|
(a._hold == b._hold) &&
|
||||||
(a._firstFrame == b._firstFrame) &&
|
(a._firstFrame == b._firstFrame) &&
|
||||||
(a._lastFrame == b._lastFrame) &&
|
(a._lastFrame == b._lastFrame) &&
|
||||||
(a._hold == b._hold);
|
(a._url == b._url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator!=(const AnimationPropertyGroup& a, const AnimationPropertyGroup& b) {
|
||||||
|
return
|
||||||
|
(a._currentFrame != b._currentFrame) ||
|
||||||
|
(a._running != b._running) ||
|
||||||
|
(a._loop != b._loop) ||
|
||||||
|
(a._hold != b._hold) ||
|
||||||
|
(a._firstFrame != b._firstFrame) ||
|
||||||
|
(a._lastFrame != b._lastFrame) ||
|
||||||
|
(a._url != b._url);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const {
|
void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const {
|
||||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_URL, Animation, animation, URL, url);
|
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_URL, Animation, animation, URL, url);
|
||||||
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_ALLOW_TRANSLATION, Animation, animation, AllowTranslation, allowTranslation);
|
COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_ALLOW_TRANSLATION, Animation, animation, AllowTranslation, allowTranslation);
|
||||||
|
@ -130,6 +143,7 @@ void AnimationPropertyGroup::setFromOldAnimationSettings(const QString& value) {
|
||||||
allowTranslation = settingsMap["allowTranslation"].toBool();
|
allowTranslation = settingsMap["allowTranslation"].toBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
setAllowTranslation(allowTranslation);
|
setAllowTranslation(allowTranslation);
|
||||||
setFPS(fps);
|
setFPS(fps);
|
||||||
setCurrentFrame(currentFrame);
|
setCurrentFrame(currentFrame);
|
||||||
|
|
|
@ -89,6 +89,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend bool operator==(const AnimationPropertyGroup& a, const AnimationPropertyGroup& b);
|
friend bool operator==(const AnimationPropertyGroup& a, const AnimationPropertyGroup& b);
|
||||||
|
friend bool operator!=(const AnimationPropertyGroup& a, const AnimationPropertyGroup& b);
|
||||||
void setFromOldAnimationSettings(const QString& value);
|
void setFromOldAnimationSettings(const QString& value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,8 @@ EntityItemPointer ModelEntityItem::factory(const EntityItemID& entityID, const E
|
||||||
|
|
||||||
ModelEntityItem::ModelEntityItem(const EntityItemID& entityItemID) : EntityItem(entityItemID)
|
ModelEntityItem::ModelEntityItem(const EntityItemID& entityItemID) : EntityItem(entityItemID)
|
||||||
{
|
{
|
||||||
|
_lastAnimated = usecTimestampNow();
|
||||||
|
// set the last animated when interface (re)starts
|
||||||
_type = EntityTypes::Model;
|
_type = EntityTypes::Model;
|
||||||
_lastKnownCurrentFrame = -1;
|
_lastKnownCurrentFrame = -1;
|
||||||
_color[0] = _color[1] = _color[2] = 0;
|
_color[0] = _color[1] = _color[2] = 0;
|
||||||
|
@ -186,6 +188,105 @@ void ModelEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// added update function back for property fix
|
||||||
|
void ModelEntityItem::update(const quint64& now) {
|
||||||
|
|
||||||
|
{
|
||||||
|
auto currentAnimationProperties = this->getAnimationProperties();
|
||||||
|
|
||||||
|
if (_previousAnimationProperties != currentAnimationProperties) {
|
||||||
|
withWriteLock([&] {
|
||||||
|
// if we hit start animation or change the first or last frame then restart the animation
|
||||||
|
if ((currentAnimationProperties.getFirstFrame() != _previousAnimationProperties.getFirstFrame()) ||
|
||||||
|
(currentAnimationProperties.getLastFrame() != _previousAnimationProperties.getLastFrame()) ||
|
||||||
|
(currentAnimationProperties.getRunning() && !_previousAnimationProperties.getRunning())) {
|
||||||
|
|
||||||
|
// when we start interface and the property is are set then the current frame is initialized to -1
|
||||||
|
if (_currentFrame < 0) {
|
||||||
|
// don't reset _lastAnimated here because we need the timestamp from the ModelEntityItem constructor for when the properties were set
|
||||||
|
_currentFrame = currentAnimationProperties.getCurrentFrame();
|
||||||
|
setAnimationCurrentFrame(_currentFrame);
|
||||||
|
} else {
|
||||||
|
_lastAnimated = usecTimestampNow();
|
||||||
|
_currentFrame = currentAnimationProperties.getFirstFrame();
|
||||||
|
setAnimationCurrentFrame(currentAnimationProperties.getFirstFrame());
|
||||||
|
}
|
||||||
|
} else if (!currentAnimationProperties.getRunning() && _previousAnimationProperties.getRunning()) {
|
||||||
|
_currentFrame = currentAnimationProperties.getFirstFrame();
|
||||||
|
setAnimationCurrentFrame(_currentFrame);
|
||||||
|
} else if (currentAnimationProperties.getCurrentFrame() != _previousAnimationProperties.getCurrentFrame()) {
|
||||||
|
// don't reset _lastAnimated here because the currentFrame was set with the previous setting of _lastAnimated
|
||||||
|
_currentFrame = currentAnimationProperties.getCurrentFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
_previousAnimationProperties = this->getAnimationProperties();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isAnimatingSomething()) {
|
||||||
|
if (!(getAnimationFirstFrame() < 0) && !(getAnimationFirstFrame() > getAnimationLastFrame())) {
|
||||||
|
updateFrameCount();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityItem::update(now);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ModelEntityItem::needsToCallUpdate() const {
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelEntityItem::updateFrameCount() {
|
||||||
|
|
||||||
|
if (_currentFrame < 0.0f) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_lastAnimated) {
|
||||||
|
_lastAnimated = usecTimestampNow();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto now = usecTimestampNow();
|
||||||
|
|
||||||
|
// update the interval since the last animation.
|
||||||
|
auto interval = now - _lastAnimated;
|
||||||
|
_lastAnimated = now;
|
||||||
|
|
||||||
|
// if fps is negative then increment timestamp and return.
|
||||||
|
if (getAnimationFPS() < 0.0f) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int updatedFrameCount = getAnimationLastFrame() - getAnimationFirstFrame() + 1;
|
||||||
|
|
||||||
|
if (!getAnimationHold() && getAnimationIsPlaying()) {
|
||||||
|
float deltaTime = (float)interval / (float)USECS_PER_SECOND;
|
||||||
|
_currentFrame += (deltaTime * getAnimationFPS());
|
||||||
|
if (_currentFrame > getAnimationLastFrame()) {
|
||||||
|
if (getAnimationLoop()) {
|
||||||
|
_currentFrame = getAnimationFirstFrame() + (int)(glm::floor(_currentFrame - getAnimationFirstFrame())) % (updatedFrameCount - 1);
|
||||||
|
} else {
|
||||||
|
_currentFrame = getAnimationLastFrame();
|
||||||
|
}
|
||||||
|
} else if (_currentFrame < getAnimationFirstFrame()) {
|
||||||
|
if (getAnimationFirstFrame() < 0) {
|
||||||
|
_currentFrame = 0;
|
||||||
|
} else {
|
||||||
|
_currentFrame = getAnimationFirstFrame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// qCDebug(entities) << "in update frame " << _currentFrame;
|
||||||
|
setAnimationCurrentFrame(_currentFrame);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void ModelEntityItem::debugDump() const {
|
void ModelEntityItem::debugDump() const {
|
||||||
qCDebug(entities) << "ModelEntityItem id:" << getEntityItemID();
|
qCDebug(entities) << "ModelEntityItem id:" << getEntityItemID();
|
||||||
qCDebug(entities) << " edited ago:" << getEditedAgo();
|
qCDebug(entities) << " edited ago:" << getEditedAgo();
|
||||||
|
@ -538,6 +639,13 @@ void ModelEntityItem::setAnimationLoop(bool loop) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ModelEntityItem::getAnimationLoop() const {
|
||||||
|
return resultWithReadLock<bool>([&] {
|
||||||
|
return _animationProperties.getLoop();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ModelEntityItem::setAnimationHold(bool hold) {
|
void ModelEntityItem::setAnimationHold(bool hold) {
|
||||||
withWriteLock([&] {
|
withWriteLock([&] {
|
||||||
_animationProperties.setHold(hold);
|
_animationProperties.setHold(hold);
|
||||||
|
@ -573,8 +681,9 @@ float ModelEntityItem::getAnimationLastFrame() const {
|
||||||
return _animationProperties.getLastFrame();
|
return _animationProperties.getLastFrame();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ModelEntityItem::getAnimationIsPlaying() const {
|
bool ModelEntityItem::getAnimationIsPlaying() const {
|
||||||
return resultWithReadLock<float>([&] {
|
return resultWithReadLock<bool>([&] {
|
||||||
return _animationProperties.getRunning();
|
return _animationProperties.getRunning();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -585,8 +694,15 @@ float ModelEntityItem::getAnimationCurrentFrame() const {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ModelEntityItem::isAnimatingSomething() const {
|
float ModelEntityItem::getAnimationFPS() const {
|
||||||
return resultWithReadLock<float>([&] {
|
return resultWithReadLock<float>([&] {
|
||||||
|
return _animationProperties.getFPS();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ModelEntityItem::isAnimatingSomething() const {
|
||||||
|
return resultWithReadLock<bool>([&] {
|
||||||
return !_animationProperties.getURL().isEmpty() &&
|
return !_animationProperties.getURL().isEmpty() &&
|
||||||
_animationProperties.getRunning() &&
|
_animationProperties.getRunning() &&
|
||||||
(_animationProperties.getFPS() != 0.0f);
|
(_animationProperties.getFPS() != 0.0f);
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <ThreadSafeValueCache.h>
|
#include <ThreadSafeValueCache.h>
|
||||||
#include "AnimationPropertyGroup.h"
|
#include "AnimationPropertyGroup.h"
|
||||||
|
|
||||||
|
|
||||||
class ModelEntityItem : public EntityItem {
|
class ModelEntityItem : public EntityItem {
|
||||||
public:
|
public:
|
||||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||||
|
@ -46,8 +47,11 @@ public:
|
||||||
EntityPropertyFlags& propertyFlags, bool overwriteLocalData,
|
EntityPropertyFlags& propertyFlags, bool overwriteLocalData,
|
||||||
bool& somethingChanged) override;
|
bool& somethingChanged) override;
|
||||||
|
|
||||||
//virtual void update(const quint64& now) override;
|
// update() and needstocallupdate() added back for the entity property fix
|
||||||
//virtual bool needsToCallUpdate() const override;
|
virtual void update(const quint64& now) override;
|
||||||
|
virtual bool needsToCallUpdate() const override;
|
||||||
|
void updateFrameCount();
|
||||||
|
|
||||||
virtual void debugDump() const override;
|
virtual void debugDump() const override;
|
||||||
|
|
||||||
void setShapeType(ShapeType type) override;
|
void setShapeType(ShapeType type) override;
|
||||||
|
@ -90,6 +94,7 @@ public:
|
||||||
bool getAnimationAllowTranslation() const { return _animationProperties.getAllowTranslation(); };
|
bool getAnimationAllowTranslation() const { return _animationProperties.getAllowTranslation(); };
|
||||||
|
|
||||||
void setAnimationLoop(bool loop);
|
void setAnimationLoop(bool loop);
|
||||||
|
bool getAnimationLoop() const;
|
||||||
|
|
||||||
void setAnimationHold(bool hold);
|
void setAnimationHold(bool hold);
|
||||||
bool getAnimationHold() const;
|
bool getAnimationHold() const;
|
||||||
|
@ -102,6 +107,7 @@ public:
|
||||||
|
|
||||||
bool getAnimationIsPlaying() const;
|
bool getAnimationIsPlaying() const;
|
||||||
float getAnimationCurrentFrame() const;
|
float getAnimationCurrentFrame() const;
|
||||||
|
float getAnimationFPS() const;
|
||||||
bool isAnimatingSomething() const;
|
bool isAnimatingSomething() const;
|
||||||
|
|
||||||
static const QString DEFAULT_TEXTURES;
|
static const QString DEFAULT_TEXTURES;
|
||||||
|
@ -147,7 +153,7 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
QVector<ModelJointData> _localJointData;
|
QVector<ModelJointData> _localJointData;
|
||||||
int _lastKnownCurrentFrame;
|
int _lastKnownCurrentFrame{-1};
|
||||||
|
|
||||||
rgbColor _color;
|
rgbColor _color;
|
||||||
QString _modelURL;
|
QString _modelURL;
|
||||||
|
@ -160,6 +166,11 @@ protected:
|
||||||
QString _textures;
|
QString _textures;
|
||||||
|
|
||||||
ShapeType _shapeType = SHAPE_TYPE_NONE;
|
ShapeType _shapeType = SHAPE_TYPE_NONE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint64_t _lastAnimated{ 0 };
|
||||||
|
AnimationPropertyGroup _previousAnimationProperties;
|
||||||
|
float _currentFrame{ -1.0f };
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_ModelEntityItem_h
|
#endif // hifi_ModelEntityItem_h
|
||||||
|
|
Loading…
Reference in a new issue