From 96705bfd74618a9db898e709e711f02952ce7d5f Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 12 Nov 2014 13:36:08 -0800 Subject: [PATCH 01/20] allow AnimationHandle to be set from AnimationDetails --- interface/src/renderer/AnimationHandle.cpp | 17 +++++++++++++++++ interface/src/renderer/AnimationHandle.h | 1 + interface/src/renderer/Model.cpp | 1 - 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/interface/src/renderer/AnimationHandle.cpp b/interface/src/renderer/AnimationHandle.cpp index 8ecf5d9699..957787abb2 100644 --- a/interface/src/renderer/AnimationHandle.cpp +++ b/interface/src/renderer/AnimationHandle.cpp @@ -97,6 +97,23 @@ AnimationDetails AnimationHandle::getAnimationDetails() const { return details; } +void AnimationHandle::setAnimationDetails(const AnimationDetails& details) { + setRole(details.role); + setURL(details.url); + setFPS(details.fps); + setPriority(details.priority); + setLoop(details.loop); + setHold(details.hold); + setStartAutomatically(details.startAutomatically); + setFirstFrame(details.firstFrame); + setLastFrame(details.lastFrame); + setRunning(details.running); + setFrameIndex(details.frameIndex); + + // NOTE: AnimationDetails doesn't support maskedJoints + //setMaskedJoints(const QStringList& maskedJoints); +} + void AnimationHandle::simulate(float deltaTime) { _frameIndex += deltaTime * _fps; diff --git a/interface/src/renderer/AnimationHandle.h b/interface/src/renderer/AnimationHandle.h index 3b736698df..48026fe4b7 100644 --- a/interface/src/renderer/AnimationHandle.h +++ b/interface/src/renderer/AnimationHandle.h @@ -70,6 +70,7 @@ public: float getFrameIndex() const { return _frameIndex; } AnimationDetails getAnimationDetails() const; + void setAnimationDetails(const AnimationDetails& details); signals: diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 7455e528b7..5369ee7fe4 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -1527,7 +1527,6 @@ void Model::endScene(RenderMode mode, RenderArgs* args) { int opaqueMeshPartsRendered = 0; // now, for each model in the scene, render the mesh portions - float alpha = 1.0f; // at this point we don't support per model alphas foreach(Model* model, _modelsInScene) { opaqueMeshPartsRendered += model->renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, args); } From 68bd6c23d9d3d6d5ba41ea9f1182f4ca8eac0aa3 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 12 Nov 2014 14:47:02 -0800 Subject: [PATCH 02/20] sepearate looping logic from AnimationHandle --- libraries/animation/src/AnimationLoop.cpp | 95 +++++++++++++++++++++++ libraries/animation/src/AnimationLoop.h | 63 +++++++++++++++ 2 files changed, 158 insertions(+) create mode 100644 libraries/animation/src/AnimationLoop.cpp create mode 100644 libraries/animation/src/AnimationLoop.h diff --git a/libraries/animation/src/AnimationLoop.cpp b/libraries/animation/src/AnimationLoop.cpp new file mode 100644 index 0000000000..f81904990f --- /dev/null +++ b/libraries/animation/src/AnimationLoop.cpp @@ -0,0 +1,95 @@ +// +// AnimationLoop.cpp +// libraries/animation +// +// Created by Brad Hefta-Gaub on 11/12/14. +// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "AnimationCache.h" +#include "AnimationLoop.h" + +AnimationLoop::AnimationLoop() : + _fps(30.0f), + _loop(false), + _hold(false), + _startAutomatically(false), + _firstFrame(0.0f), + _lastFrame(FLT_MAX), + _running(false), + _frameIndex(0.0f) +{ +} + +AnimationLoop::AnimationLoop(const AnimationDetails& animationDetails) : + _fps(animationDetails.fps), + _loop(animationDetails.loop), + _hold(animationDetails.hold), + _startAutomatically(animationDetails.startAutomatically), + _firstFrame(animationDetails.firstFrame), + _lastFrame(animationDetails.lastFrame), + _running(animationDetails.running), + _frameIndex(animationDetails.frameIndex) +{ +} + +AnimationLoop::AnimationLoop(float fps, bool loop, bool hold, bool startAutomatically, float firstFrame, + float lastFrame, bool running, float frameIndex) : + _fps(fps), + _loop(loop), + _hold(hold), + _startAutomatically(startAutomatically), + _firstFrame(firstFrame), + _lastFrame(lastFrame), + _running(running), + _frameIndex(frameIndex) +{ +} + +void AnimationLoop::simulate(float deltaTime) { + _frameIndex += deltaTime * _fps; + + + // If we knew the number of frames from the animation, we'd consider using it here + // animationGeometry.animationFrames.size() + float maxFrame = _lastFrame; + float endFrameIndex = qMin(_lastFrame, maxFrame - (_loop ? 0.0f : 1.0f)); + float startFrameIndex = qMin(_firstFrame, endFrameIndex); + if ((!_loop && (_frameIndex < startFrameIndex || _frameIndex > endFrameIndex)) || startFrameIndex == endFrameIndex) { + // passed the end; apply the last frame + _frameIndex = glm::clamp(_frameIndex, startFrameIndex, endFrameIndex); + if (!_hold) { + stop(); + } + } else { + // wrap within the the desired range + if (_frameIndex < startFrameIndex) { + _frameIndex = endFrameIndex - glm::mod(endFrameIndex - _frameIndex, endFrameIndex - startFrameIndex); + + } else if (_frameIndex > endFrameIndex) { + _frameIndex = startFrameIndex + glm::mod(_frameIndex - startFrameIndex, endFrameIndex - startFrameIndex); + } + } +} + +void AnimationLoop::setStartAutomatically(bool startAutomatically) { + if ((_startAutomatically = startAutomatically) && !isRunning()) { + start(); + } +} + +void AnimationLoop::setRunning(bool running) { + if (_running == running) { + if (running) { + // move back to the beginning + _frameIndex = _firstFrame; + } + return; + } + if ((_running = running)) { + _frameIndex = _firstFrame; + } +} diff --git a/libraries/animation/src/AnimationLoop.h b/libraries/animation/src/AnimationLoop.h new file mode 100644 index 0000000000..33d4d8e5bc --- /dev/null +++ b/libraries/animation/src/AnimationLoop.h @@ -0,0 +1,63 @@ +// +// AnimationLoop.h +// libraries/script-engine/src/ +// +// Created by Brad Hefta-Gaub on 11/12/14. +// Copyright (c) 2014 High Fidelity, Inc. All rights reserved. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_AnimationLoop_h +#define hifi_AnimationLoop_h + +class AnimationDetails; + +class AnimationLoop { +public: + AnimationLoop(); + AnimationLoop(const AnimationDetails& animationDetails); + AnimationLoop(float fps, bool loop, bool hold, bool startAutomatically, float firstFrame, + float lastFrame, bool running, float frameIndex); + + void setFPS(float fps) { _fps = fps; } + float getFPS() const { return _fps; } + + void setLoop(bool loop) { _loop = loop; } + bool getLoop() const { return _loop; } + + void setHold(bool hold) { _hold = hold; } + bool getHold() const { return _hold; } + + void setStartAutomatically(bool startAutomatically); + bool getStartAutomatically() const { return _startAutomatically; } + + void setFirstFrame(float firstFrame) { _firstFrame = firstFrame; } + float getFirstFrame() const { return _firstFrame; } + + void setLastFrame(float lastFrame) { _lastFrame = lastFrame; } + float getLastFrame() const { return _lastFrame; } + + void setRunning(bool running); + bool isRunning() const { return _running; } + + void setFrameIndex(float frameIndex) { _frameIndex = glm::clamp(_frameIndex, _firstFrame, _lastFrame); } + float getFrameIndex() const { return _frameIndex; } + + void start() { setRunning(true); } + void stop() { setRunning(false); } + void simulate(float deltaTime); + +private: + float _fps; + bool _loop; + bool _hold; + bool _startAutomatically; + float _firstFrame; + float _lastFrame; + bool _running; + float _frameIndex; +}; + +#endif // hifi_AnimationLoop_h From 6ff8abcbdd45bf0ab77353861422e85c4b83076f Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 12 Nov 2014 14:47:10 -0800 Subject: [PATCH 03/20] sepearate looping logic from AnimationHandle --- interface/src/renderer/AnimationHandle.cpp | 38 +++++++------- interface/src/renderer/AnimationHandle.h | 60 ++++++++++++---------- libraries/animation/src/AnimationCache.h | 1 - 3 files changed, 52 insertions(+), 47 deletions(-) diff --git a/interface/src/renderer/AnimationHandle.cpp b/interface/src/renderer/AnimationHandle.cpp index 957787abb2..caddd8c4b6 100644 --- a/interface/src/renderer/AnimationHandle.cpp +++ b/interface/src/renderer/AnimationHandle.cpp @@ -33,7 +33,7 @@ void AnimationHandle::setPriority(float priority) { if (_priority == priority) { return; } - if (_running) { + if (isRunning()) { _model->_runningAnimations.removeOne(_self); if (priority < _priority) { replaceMatchingPriorities(priority); @@ -47,7 +47,8 @@ void AnimationHandle::setPriority(float priority) { } void AnimationHandle::setStartAutomatically(bool startAutomatically) { - if ((_startAutomatically = startAutomatically) && !_running) { + _animationLoop.setStartAutomatically(startAutomatically); + if (getStartAutomatically() && !isRunning()) { start(); } } @@ -58,42 +59,36 @@ void AnimationHandle::setMaskedJoints(const QStringList& maskedJoints) { } void AnimationHandle::setRunning(bool running) { - if (_running == running) { + if (isRunning() == running) { + // if we're already running, this is the same as a restart if (running) { // move back to the beginning - _frameIndex = _firstFrame; + setFrameIndex(getFirstFrame()); } return; } - if ((_running = running)) { + _animationLoop.setRunning(running); + if (isRunning()) { if (!_model->_runningAnimations.contains(_self)) { insertSorted(_model->_runningAnimations, _self); } - _frameIndex = _firstFrame; - } else { _model->_runningAnimations.removeOne(_self); replaceMatchingPriorities(0.0f); } - emit runningChanged(_running); + emit runningChanged(isRunning()); } AnimationHandle::AnimationHandle(Model* model) : QObject(model), _model(model), - _fps(30.0f), - _priority(1.0f), - _loop(false), - _hold(false), - _startAutomatically(false), - _firstFrame(0.0f), - _lastFrame(FLT_MAX), - _running(false) { + _priority(1.0f) +{ } AnimationDetails AnimationHandle::getAnimationDetails() const { - AnimationDetails details(_role, _url, _fps, _priority, _loop, _hold, - _startAutomatically, _firstFrame, _lastFrame, _running, _frameIndex); + AnimationDetails details(_role, _url, getFPS(), _priority, getLoop(), getHold(), + getStartAutomatically(), getFirstFrame(), getLastFrame(), isRunning(), getFrameIndex()); return details; } @@ -116,7 +111,7 @@ void AnimationHandle::setAnimationDetails(const AnimationDetails& details) { void AnimationHandle::simulate(float deltaTime) { - _frameIndex += deltaTime * _fps; + _animationLoop.simulate(deltaTime); // update the joint mappings if necessary/possible if (_jointMappings.isEmpty()) { @@ -142,6 +137,8 @@ void AnimationHandle::simulate(float deltaTime) { stop(); return; } + + /* float endFrameIndex = qMin(_lastFrame, animationGeometry.animationFrames.size() - (_loop ? 0.0f : 1.0f)); float startFrameIndex = qMin(_firstFrame, endFrameIndex); if ((!_loop && (_frameIndex < startFrameIndex || _frameIndex > endFrameIndex)) || startFrameIndex == endFrameIndex) { @@ -159,9 +156,10 @@ void AnimationHandle::simulate(float deltaTime) { } else if (_frameIndex > endFrameIndex) { _frameIndex = startFrameIndex + glm::mod(_frameIndex - startFrameIndex, endFrameIndex - startFrameIndex); } + */ // blend between the closest two frames - applyFrame(_frameIndex); + applyFrame(getFrameIndex()); } void AnimationHandle::applyFrame(float frameIndex) { diff --git a/interface/src/renderer/AnimationHandle.h b/interface/src/renderer/AnimationHandle.h index 48026fe4b7..aa030e6350 100644 --- a/interface/src/renderer/AnimationHandle.h +++ b/interface/src/renderer/AnimationHandle.h @@ -19,6 +19,7 @@ #include #include +#include class AnimationHandle; class Model; @@ -38,36 +39,37 @@ public: void setURL(const QUrl& url); const QUrl& getURL() const { return _url; } - - void setFPS(float fps) { _fps = fps; } - float getFPS() const { return _fps; } void setPriority(float priority); float getPriority() const { return _priority; } - - void setLoop(bool loop) { _loop = loop; } - bool getLoop() const { return _loop; } - - void setHold(bool hold) { _hold = hold; } - bool getHold() const { return _hold; } - - void setStartAutomatically(bool startAutomatically); - bool getStartAutomatically() const { return _startAutomatically; } - - void setFirstFrame(float firstFrame) { _firstFrame = firstFrame; } - float getFirstFrame() const { return _firstFrame; } - - void setLastFrame(float lastFrame) { _lastFrame = lastFrame; } - float getLastFrame() const { return _lastFrame; } - + void setMaskedJoints(const QStringList& maskedJoints); const QStringList& getMaskedJoints() const { return _maskedJoints; } - void setRunning(bool running); - bool isRunning() const { return _running; } - void setFrameIndex(float frameIndex) { _frameIndex = glm::clamp(_frameIndex, _firstFrame, _lastFrame); } - float getFrameIndex() const { return _frameIndex; } + void setFPS(float fps) { _animationLoop.setFPS(fps); } + float getFPS() const { return _animationLoop.getFPS(); } + + void setLoop(bool loop) { _animationLoop.setLoop(loop); } + bool getLoop() const { return _animationLoop.getLoop(); } + + void setHold(bool hold) { _animationLoop.setHold(hold); } + bool getHold() const { return _animationLoop.getHold(); } + + void setStartAutomatically(bool startAutomatically); + bool getStartAutomatically() const { return _animationLoop.getStartAutomatically(); } + + void setFirstFrame(float firstFrame) { _animationLoop.setFirstFrame(firstFrame); } + float getFirstFrame() const { return _animationLoop.getFirstFrame(); } + + void setLastFrame(float lastFrame) { _animationLoop.setLastFrame(lastFrame); } + float getLastFrame() const { return _animationLoop.getLastFrame(); } + + void setRunning(bool running); + bool isRunning() const { return _animationLoop.isRunning(); } + + void setFrameIndex(float frameIndex) { _animationLoop.setFrameIndex(frameIndex); } + float getFrameIndex() const { return _animationLoop.getFrameIndex(); } AnimationDetails getAnimationDetails() const; void setAnimationDetails(const AnimationDetails& details); @@ -96,17 +98,23 @@ private: AnimationPointer _animation; QString _role; QUrl _url; - float _fps; float _priority; + + QStringList _maskedJoints; + QVector _jointMappings; + + AnimationLoop _animationLoop; + + /* + float _fps; bool _loop; bool _hold; bool _startAutomatically; float _firstFrame; float _lastFrame; - QStringList _maskedJoints; bool _running; - QVector _jointMappings; float _frameIndex; + */ }; diff --git a/libraries/animation/src/AnimationCache.h b/libraries/animation/src/AnimationCache.h index 4af9f0a83f..8a9e371cb0 100644 --- a/libraries/animation/src/AnimationCache.h +++ b/libraries/animation/src/AnimationCache.h @@ -94,5 +94,4 @@ Q_DECLARE_METATYPE(AnimationDetails); QScriptValue animationDetailsToScriptValue(QScriptEngine* engine, const AnimationDetails& event); void animationDetailsFromScriptValue(const QScriptValue& object, AnimationDetails& event); - #endif // hifi_AnimationCache_h From d2ab3e69f09b27ffcd6e9e3eb7433a86fc8f15ad Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 12 Nov 2014 14:59:03 -0800 Subject: [PATCH 04/20] some cleanup --- interface/src/renderer/AnimationHandle.cpp | 26 +++++----------------- interface/src/renderer/AnimationHandle.h | 11 --------- 2 files changed, 6 insertions(+), 31 deletions(-) diff --git a/interface/src/renderer/AnimationHandle.cpp b/interface/src/renderer/AnimationHandle.cpp index caddd8c4b6..767f941049 100644 --- a/interface/src/renderer/AnimationHandle.cpp +++ b/interface/src/renderer/AnimationHandle.cpp @@ -138,26 +138,12 @@ void AnimationHandle::simulate(float deltaTime) { return; } - /* - float endFrameIndex = qMin(_lastFrame, animationGeometry.animationFrames.size() - (_loop ? 0.0f : 1.0f)); - float startFrameIndex = qMin(_firstFrame, endFrameIndex); - if ((!_loop && (_frameIndex < startFrameIndex || _frameIndex > endFrameIndex)) || startFrameIndex == endFrameIndex) { - // passed the end; apply the last frame - applyFrame(glm::clamp(_frameIndex, startFrameIndex, endFrameIndex)); - if (!_hold) { - stop(); - } - return; - } - // wrap within the the desired range - if (_frameIndex < startFrameIndex) { - _frameIndex = endFrameIndex - glm::mod(endFrameIndex - _frameIndex, endFrameIndex - startFrameIndex); - - } else if (_frameIndex > endFrameIndex) { - _frameIndex = startFrameIndex + glm::mod(_frameIndex - startFrameIndex, endFrameIndex - startFrameIndex); - } - */ - + // TODO: When moving the loop/frame calculations to AnimationLoop class, we changed this behavior + // see AnimationLoop class for more details. Do we need to support clamping the endFrameIndex to + // the max number of frames in the geometry??? + // + // float endFrameIndex = qMin(_lastFrame, animationGeometry.animationFrames.size() - (_loop ? 0.0f : 1.0f)); + // blend between the closest two frames applyFrame(getFrameIndex()); } diff --git a/interface/src/renderer/AnimationHandle.h b/interface/src/renderer/AnimationHandle.h index aa030e6350..3956b01ebf 100644 --- a/interface/src/renderer/AnimationHandle.h +++ b/interface/src/renderer/AnimationHandle.h @@ -104,17 +104,6 @@ private: QVector _jointMappings; AnimationLoop _animationLoop; - - /* - float _fps; - bool _loop; - bool _hold; - bool _startAutomatically; - float _firstFrame; - float _lastFrame; - bool _running; - float _frameIndex; - */ }; From 245f019836a637cac46d52e5516c153ae4e9bba9 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 12 Nov 2014 16:10:35 -0800 Subject: [PATCH 05/20] first cut at migrating entity animation frame calculations to use AnimationLoop --- .../entities/src/EntityItemPropertiesMacros.h | 12 ++++++ libraries/entities/src/ModelEntityItem.cpp | 37 +++++++++++-------- libraries/entities/src/ModelEntityItem.h | 18 ++++----- 3 files changed, 43 insertions(+), 24 deletions(-) diff --git a/libraries/entities/src/EntityItemPropertiesMacros.h b/libraries/entities/src/EntityItemPropertiesMacros.h index b5a489f88c..77782cb90f 100644 --- a/libraries/entities/src/EntityItemPropertiesMacros.h +++ b/libraries/entities/src/EntityItemPropertiesMacros.h @@ -40,6 +40,18 @@ } \ } +#define READ_ENTITY_PROPERTY_SETTER(P,T,M) \ + if (propertyFlags.getHasProperty(P)) { \ + T fromBuffer; \ + memcpy(&fromBuffer, dataAt, sizeof(fromBuffer)); \ + dataAt += sizeof(fromBuffer); \ + bytesRead += sizeof(fromBuffer); \ + if (overwriteLocalData) { \ + M(fromBuffer); \ + } \ + } + + #define READ_ENTITY_PROPERTY_QUAT(P,M) \ if (propertyFlags.getHasProperty(P)) { \ glm::quat fromBuffer; \ diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 827f4f7e39..339f630f35 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -33,10 +33,11 @@ ModelEntityItem::ModelEntityItem(const EntityItemID& entityItemID, const EntityI { _type = EntityTypes::Model; setProperties(properties, true); - _animationFrameIndex = 0.0f; _lastAnimated = usecTimestampNow(); _jointMappingCompleted = false; _color[0] = _color[1] = _color[2] = 0; + + //_animationFrameIndex = 0.0f; } EntityItemProperties ModelEntityItem::getProperties() const { @@ -100,9 +101,9 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, READ_ENTITY_PROPERTY_COLOR(PROP_COLOR, _color); READ_ENTITY_PROPERTY_STRING(PROP_MODEL_URL, setModelURL); READ_ENTITY_PROPERTY_STRING(PROP_ANIMATION_URL, setAnimationURL); - READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, _animationFPS); - READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, _animationFrameIndex); - READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, _animationIsPlaying); + READ_ENTITY_PROPERTY_SETTER(PROP_ANIMATION_FPS, float, setAnimationFPS); + READ_ENTITY_PROPERTY_SETTER(PROP_ANIMATION_FRAME_INDEX, float, setAnimationFrameIndex); + READ_ENTITY_PROPERTY_SETTER(PROP_ANIMATION_PLAYING, bool, setAnimationIsPlaying); READ_ENTITY_PROPERTY_STRING(PROP_TEXTURES, setTextures); return bytesRead; @@ -199,19 +200,25 @@ int ModelEntityItem::oldVersionReadEntityDataFromBuffer(const unsigned char* dat bytesRead += animationURLLength; // animationIsPlaying - memcpy(&_animationIsPlaying, dataAt, sizeof(_animationIsPlaying)); - dataAt += sizeof(_animationIsPlaying); - bytesRead += sizeof(_animationIsPlaying); + bool animationIsPlaying; + memcpy(&animationIsPlaying, dataAt, sizeof(animationIsPlaying)); + dataAt += sizeof(animationIsPlaying); + bytesRead += sizeof(animationIsPlaying); + setAnimationIsPlaying(animationIsPlaying); // animationFrameIndex - memcpy(&_animationFrameIndex, dataAt, sizeof(_animationFrameIndex)); - dataAt += sizeof(_animationFrameIndex); - bytesRead += sizeof(_animationFrameIndex); + float animationFrameIndex; + memcpy(&animationFrameIndex, dataAt, sizeof(animationFrameIndex)); + dataAt += sizeof(animationFrameIndex); + bytesRead += sizeof(animationFrameIndex); + setAnimationFrameIndex(animationFrameIndex); // animationFPS - memcpy(&_animationFPS, dataAt, sizeof(_animationFPS)); - dataAt += sizeof(_animationFPS); - bytesRead += sizeof(_animationFPS); + float animationFPS; + memcpy(&animationFPS, dataAt, sizeof(animationFPS)); + dataAt += sizeof(animationFPS); + bytesRead += sizeof(animationFPS); + setAnimationFPS(animationFPS); } } return bytesRead; @@ -314,7 +321,7 @@ QVector ModelEntityItem::getAnimationFrame() { int frameCount = frames.size(); if (frameCount > 0) { - int animationFrameIndex = (int)(glm::floor(_animationFrameIndex)) % frameCount; + int animationFrameIndex = (int)(glm::floor(getAnimationFrameIndex())) % frameCount; if (animationFrameIndex < 0 || animationFrameIndex > frameCount) { animationFrameIndex = 0; @@ -363,7 +370,7 @@ void ModelEntityItem::update(const quint64& updateTime) { if (getAnimationIsPlaying()) { float deltaTime = (float)(now - _lastAnimated) / (float)USECS_PER_SECOND; _lastAnimated = now; - _animationFrameIndex += deltaTime * _animationFPS; + _animationLoop.simulate(deltaTime); } else { _lastAnimated = now; } diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index 4c79a46c5e..aea9407e8b 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -12,6 +12,8 @@ #ifndef hifi_ModelEntityItem_h #define hifi_ModelEntityItem_h +#include + #include "EntityItem.h" class ModelEntityItem : public EntityItem { @@ -73,21 +75,21 @@ public: void setModelURL(const QString& url) { _modelURL = url; } void setAnimationURL(const QString& url) { _animationURL = url; } static const float DEFAULT_ANIMATION_FRAME_INDEX; - void setAnimationFrameIndex(float value) { _animationFrameIndex = value; } + void setAnimationFrameIndex(float value) { _animationLoop.setFrameIndex(value); } static const bool DEFAULT_ANIMATION_IS_PLAYING; - void setAnimationIsPlaying(bool value) { _animationIsPlaying = value; } + void setAnimationIsPlaying(bool value) { _animationLoop.setRunning(value); } static const float DEFAULT_ANIMATION_FPS; - void setAnimationFPS(float value) { _animationFPS = value; } + void setAnimationFPS(float value) { _animationLoop.setFPS(value); } void mapJoints(const QStringList& modelJointNames); QVector getAnimationFrame(); bool jointsMapped() const { return _jointMappingCompleted; } - bool getAnimationIsPlaying() const { return _animationIsPlaying; } - float getAnimationFrameIndex() const { return _animationFrameIndex; } - float getAnimationFPS() const { return _animationFPS; } + bool getAnimationIsPlaying() const { return _animationLoop.isRunning(); } + float getAnimationFrameIndex() const { return _animationLoop.getFrameIndex(); } + float getAnimationFPS() const { return _animationLoop.getFPS(); } static const QString DEFAULT_TEXTURES; const QString& getTextures() const { return _textures; } @@ -106,9 +108,7 @@ protected: quint64 _lastAnimated; QString _animationURL; - float _animationFrameIndex; // we keep this as a float and round to int only when we need the exact index - bool _animationIsPlaying; - float _animationFPS; + AnimationLoop _animationLoop; QString _textures; // used on client side From ba79f40007ad42225cbefcd4d613f4c363cf1c8d Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 12 Nov 2014 16:12:34 -0800 Subject: [PATCH 06/20] add some debug --- libraries/animation/src/AnimationLoop.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/animation/src/AnimationLoop.cpp b/libraries/animation/src/AnimationLoop.cpp index f81904990f..6943b2e010 100644 --- a/libraries/animation/src/AnimationLoop.cpp +++ b/libraries/animation/src/AnimationLoop.cpp @@ -73,6 +73,10 @@ void AnimationLoop::simulate(float deltaTime) { _frameIndex = startFrameIndex + glm::mod(_frameIndex - startFrameIndex, endFrameIndex - startFrameIndex); } } + + qDebug() << "AnimationLoop::simulate()"; + qDebug() << " deltaTime:" << deltaTime; + qDebug() << " _frameIndex:" << _frameIndex; } void AnimationLoop::setStartAutomatically(bool startAutomatically) { From dd22683672f99cbe21587fa5d212c7bf8b970e6c Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 12 Nov 2014 16:53:16 -0800 Subject: [PATCH 07/20] fixing up animation loop issues --- libraries/animation/src/AnimationLoop.cpp | 4 +++- libraries/animation/src/AnimationLoop.h | 2 +- libraries/entities/src/ModelEntityItem.cpp | 20 +++++++++++++++++--- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/libraries/animation/src/AnimationLoop.cpp b/libraries/animation/src/AnimationLoop.cpp index 6943b2e010..27039da4ad 100644 --- a/libraries/animation/src/AnimationLoop.cpp +++ b/libraries/animation/src/AnimationLoop.cpp @@ -73,10 +73,12 @@ void AnimationLoop::simulate(float deltaTime) { _frameIndex = startFrameIndex + glm::mod(_frameIndex - startFrameIndex, endFrameIndex - startFrameIndex); } } - + + /* qDebug() << "AnimationLoop::simulate()"; qDebug() << " deltaTime:" << deltaTime; qDebug() << " _frameIndex:" << _frameIndex; + */ } void AnimationLoop::setStartAutomatically(bool startAutomatically) { diff --git a/libraries/animation/src/AnimationLoop.h b/libraries/animation/src/AnimationLoop.h index 33d4d8e5bc..b56f68f23b 100644 --- a/libraries/animation/src/AnimationLoop.h +++ b/libraries/animation/src/AnimationLoop.h @@ -42,7 +42,7 @@ public: void setRunning(bool running); bool isRunning() const { return _running; } - void setFrameIndex(float frameIndex) { _frameIndex = glm::clamp(_frameIndex, _firstFrame, _lastFrame); } + void setFrameIndex(float frameIndex) { _frameIndex = glm::clamp(frameIndex, _firstFrame, _lastFrame); } float getFrameIndex() const { return _frameIndex; } void start() { setRunning(true); } diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 339f630f35..bc0ade66f4 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -101,9 +101,23 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, READ_ENTITY_PROPERTY_COLOR(PROP_COLOR, _color); READ_ENTITY_PROPERTY_STRING(PROP_MODEL_URL, setModelURL); READ_ENTITY_PROPERTY_STRING(PROP_ANIMATION_URL, setAnimationURL); - READ_ENTITY_PROPERTY_SETTER(PROP_ANIMATION_FPS, float, setAnimationFPS); - READ_ENTITY_PROPERTY_SETTER(PROP_ANIMATION_FRAME_INDEX, float, setAnimationFrameIndex); - READ_ENTITY_PROPERTY_SETTER(PROP_ANIMATION_PLAYING, bool, setAnimationIsPlaying); + + // Because we're using AnimationLoop which will reset the frame index if you change it's running state + // we want to read these values in the order they appear in the buffer, but call our setters in an + // order that allows AnimationLoop to preserve the correct frame rate. + float animationFPS = getAnimationFPS(); + float animationFrameIndex = getAnimationFrameIndex(); + bool animationIsPlaying = getAnimationIsPlaying(); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, animationFPS); + READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, animationFrameIndex); + READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, animationIsPlaying); + + setAnimationIsPlaying(animationIsPlaying); + setAnimationFPS(animationFPS); + setAnimationFrameIndex(animationFrameIndex); + +qDebug() << "just read PROP_ANIMATION_FRAME_INDEX, getAnimationFrameIndex():" << getAnimationFrameIndex(); + READ_ENTITY_PROPERTY_STRING(PROP_TEXTURES, setTextures); return bytesRead; From ef17659ea21f54518e0d3a011388b78399675d45 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 12 Nov 2014 16:57:42 -0800 Subject: [PATCH 08/20] cleanup --- libraries/animation/src/AnimationLoop.cpp | 6 ------ libraries/entities/src/ModelEntityItem.cpp | 4 ---- 2 files changed, 10 deletions(-) diff --git a/libraries/animation/src/AnimationLoop.cpp b/libraries/animation/src/AnimationLoop.cpp index 27039da4ad..f81904990f 100644 --- a/libraries/animation/src/AnimationLoop.cpp +++ b/libraries/animation/src/AnimationLoop.cpp @@ -73,12 +73,6 @@ void AnimationLoop::simulate(float deltaTime) { _frameIndex = startFrameIndex + glm::mod(_frameIndex - startFrameIndex, endFrameIndex - startFrameIndex); } } - - /* - qDebug() << "AnimationLoop::simulate()"; - qDebug() << " deltaTime:" << deltaTime; - qDebug() << " _frameIndex:" << _frameIndex; - */ } void AnimationLoop::setStartAutomatically(bool startAutomatically) { diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index bc0ade66f4..265476b09d 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -36,8 +36,6 @@ ModelEntityItem::ModelEntityItem(const EntityItemID& entityItemID, const EntityI _lastAnimated = usecTimestampNow(); _jointMappingCompleted = false; _color[0] = _color[1] = _color[2] = 0; - - //_animationFrameIndex = 0.0f; } EntityItemProperties ModelEntityItem::getProperties() const { @@ -116,8 +114,6 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, setAnimationFPS(animationFPS); setAnimationFrameIndex(animationFrameIndex); -qDebug() << "just read PROP_ANIMATION_FRAME_INDEX, getAnimationFrameIndex():" << getAnimationFrameIndex(); - READ_ENTITY_PROPERTY_STRING(PROP_TEXTURES, setTextures); return bytesRead; From 8a2e3d5045e214c97c714c54c6bedf0ae7d2ab7f Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 12 Nov 2014 17:41:55 -0800 Subject: [PATCH 09/20] add animationSettings property to model entities --- examples/libraries/entityPropertyDialogBox.js | 3 +++ libraries/entities/src/EntityItemProperties.cpp | 13 +++++++++++-- libraries/entities/src/EntityItemProperties.h | 11 ++++++++++- libraries/entities/src/ModelEntityItem.cpp | 5 +++++ libraries/entities/src/ModelEntityItem.h | 3 +++ 5 files changed, 32 insertions(+), 3 deletions(-) diff --git a/examples/libraries/entityPropertyDialogBox.js b/examples/libraries/entityPropertyDialogBox.js index ef597549f2..d4ece08bf4 100644 --- a/examples/libraries/entityPropertyDialogBox.js +++ b/examples/libraries/entityPropertyDialogBox.js @@ -52,6 +52,8 @@ EntityPropertyDialogBox = (function () { index++; array.push({ label: "Animation Frame:", value: properties.animationFrameIndex }); index++; + array.push({ label: "Animation Settings:", value: properties.animationSettings }); + index++; array.push({ label: "Textures:", value: properties.textures }); index++; array.push({ label: "Original Textures:\n" + properties.originalTextures, type: "header" }); @@ -240,6 +242,7 @@ EntityPropertyDialogBox = (function () { properties.animationIsPlaying = array[index++].value; properties.animationFPS = array[index++].value; properties.animationFrameIndex = array[index++].value; + properties.animationSettings = array[index++].value; properties.textures = array[index++].value; index++; // skip textureNames label } diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index cb6d9c7bcd..e259c5c982 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -66,6 +66,7 @@ EntityItemProperties::EntityItemProperties() : _animationIsPlaying(ModelEntityItem::DEFAULT_ANIMATION_IS_PLAYING), _animationFrameIndex(ModelEntityItem::DEFAULT_ANIMATION_FRAME_INDEX), _animationFPS(ModelEntityItem::DEFAULT_ANIMATION_FPS), + _animationSettings(""), _glowLevel(0.0f), _localRenderAlpha(1.0f), _isSpotlight(false), @@ -76,6 +77,8 @@ EntityItemProperties::EntityItemProperties() : _animationIsPlayingChanged(false), _animationFrameIndexChanged(false), _animationFPSChanged(false), + _animationSettingsChanged(false), + _glowLevelChanged(false), _localRenderAlphaChanged(false), _isSpotlightChanged(false), @@ -149,6 +152,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_ANIMATION_PLAYING, animationIsPlaying); CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FRAME_INDEX, animationFrameIndex); CHECK_PROPERTY_CHANGE(PROP_ANIMATION_FPS, animationFPS); + CHECK_PROPERTY_CHANGE(PROP_ANIMATION_SETTINGS, animationSettings); CHECK_PROPERTY_CHANGE(PROP_VISIBLE, visible); CHECK_PROPERTY_CHANGE(PROP_REGISTRATION_POINT, registrationPoint); CHECK_PROPERTY_CHANGE(PROP_ANGULAR_VELOCITY, angularVelocity); @@ -201,8 +205,9 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine) cons COPY_PROPERTY_TO_QSCRIPTVALUE(modelURL); COPY_PROPERTY_TO_QSCRIPTVALUE(animationURL); COPY_PROPERTY_TO_QSCRIPTVALUE(animationIsPlaying); - COPY_PROPERTY_TO_QSCRIPTVALUE(animationFrameIndex); COPY_PROPERTY_TO_QSCRIPTVALUE(animationFPS); + COPY_PROPERTY_TO_QSCRIPTVALUE(animationFrameIndex); + COPY_PROPERTY_TO_QSCRIPTVALUE(animationSettings); COPY_PROPERTY_TO_QSCRIPTVALUE(glowLevel); COPY_PROPERTY_TO_QSCRIPTVALUE(localRenderAlpha); COPY_PROPERTY_TO_QSCRIPTVALUE(ignoreForCollisions); @@ -276,6 +281,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object) { COPY_PROPERTY_FROM_QSCRIPTVALUE_BOOL(animationIsPlaying, setAnimationIsPlaying); COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(animationFPS, setAnimationFPS); COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(animationFrameIndex, setAnimationFrameIndex); + COPY_PROPERTY_FROM_QSCRIPTVALUE_STRING(animationSettings, setAnimationSettings); COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(glowLevel, setGlowLevel); COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(localRenderAlpha, setLocalRenderAlpha); COPY_PROPERTY_FROM_QSCRIPTVALUE_BOOL(ignoreForCollisions, setIgnoreForCollisions); @@ -452,6 +458,7 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem APPEND_ENTITY_PROPERTY(PROP_CUTOFF, appendValue, properties.getCutoff()); APPEND_ENTITY_PROPERTY(PROP_LOCKED, appendValue, properties.getLocked()); APPEND_ENTITY_PROPERTY(PROP_TEXTURES, appendValue, properties.getTextures()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, appendValue, properties.getAnimationSettings()); } if (propertyCount > 0) { int endOfEntityItemData = packetData->getUncompressedByteOffset(); @@ -661,7 +668,8 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_CUTOFF, float, setCutoff); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LOCKED, bool, setLocked); READ_ENTITY_PROPERTY_STRING_TO_PROPERTIES(PROP_TEXTURES, setTextures); - + READ_ENTITY_PROPERTY_STRING_TO_PROPERTIES(PROP_ANIMATION_SETTINGS, setAnimationSettings); + return valid; } @@ -714,6 +722,7 @@ void EntityItemProperties::markAllChanged() { _animationIsPlayingChanged = true; _animationFrameIndexChanged = true; _animationFPSChanged = true; + _animationSettingsChanged = true; _glowLevelChanged = true; _localRenderAlphaChanged = true; _isSpotlightChanged = true; diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 6b22e8cba9..6cc205c1a2 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -80,8 +80,9 @@ enum EntityPropertyList { // used by Model entities PROP_TEXTURES, + PROP_ANIMATION_SETTINGS, - PROP_LAST_ITEM = PROP_CUTOFF + PROP_LAST_ITEM = PROP_ANIMATION_SETTINGS }; typedef PropertyFlags EntityPropertyFlags; @@ -178,6 +179,8 @@ public: float getAnimationFrameIndex() const { return _animationFrameIndex; } bool getAnimationIsPlaying() const { return _animationIsPlaying; } float getAnimationFPS() const { return _animationFPS; } + const QString& getAnimationSettings() const { return _animationSettings; } + float getGlowLevel() const { return _glowLevel; } float getLocalRenderAlpha() const { return _localRenderAlpha; } const QString& getScript() const { return _script; } @@ -189,6 +192,10 @@ public: void setAnimationFrameIndex(float value) { _animationFrameIndex = value; _animationFrameIndexChanged = true; } void setAnimationIsPlaying(bool value) { _animationIsPlaying = value; _animationIsPlayingChanged = true; } void setAnimationFPS(float value) { _animationFPS = value; _animationFPSChanged = true; } + void setAnimationSettings(const QString& value) + { _animationSettings = value; _animationSettingsChanged = true; } + + void setGlowLevel(float value) { _glowLevel = value; _glowLevelChanged = true; } void setLocalRenderAlpha(float value) { _localRenderAlpha = value; _localRenderAlphaChanged = true; } void setScript(const QString& value) { _script = value; _scriptChanged = true; } @@ -342,6 +349,7 @@ private: bool _animationIsPlaying; float _animationFrameIndex; float _animationFPS; + QString _animationSettings; float _glowLevel; float _localRenderAlpha; bool _isSpotlight; @@ -352,6 +360,7 @@ private: bool _animationIsPlayingChanged; bool _animationFrameIndexChanged; bool _animationFPSChanged; + bool _animationSettingsChanged; bool _glowLevelChanged; bool _localRenderAlphaChanged; bool _isSpotlightChanged; diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 265476b09d..095b1099b2 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -49,6 +49,7 @@ EntityItemProperties ModelEntityItem::getProperties() const { COPY_ENTITY_PROPERTY_TO_PROPERTIES(animationFPS, getAnimationFPS); COPY_ENTITY_PROPERTY_TO_PROPERTIES(glowLevel, getGlowLevel); COPY_ENTITY_PROPERTY_TO_PROPERTIES(textures, getTextures); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(animationSettings, getAnimationSettings); return properties; } @@ -63,6 +64,7 @@ bool ModelEntityItem::setProperties(const EntityItemProperties& properties, bool SET_ENTITY_PROPERTY_FROM_PROPERTIES(animationFrameIndex, setAnimationFrameIndex); SET_ENTITY_PROPERTY_FROM_PROPERTIES(animationFPS, setAnimationFPS); SET_ENTITY_PROPERTY_FROM_PROPERTIES(textures, setTextures); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(animationSettings, setAnimationSettings); if (somethingChanged) { bool wantDebug = false; @@ -115,6 +117,7 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, setAnimationFrameIndex(animationFrameIndex); READ_ENTITY_PROPERTY_STRING(PROP_TEXTURES, setTextures); + READ_ENTITY_PROPERTY_STRING(PROP_ANIMATION_SETTINGS, setAnimationSettings); return bytesRead; } @@ -244,6 +247,7 @@ EntityPropertyFlags ModelEntityItem::getEntityProperties(EncodeBitstreamParams& requestedProperties += PROP_ANIMATION_FPS; requestedProperties += PROP_ANIMATION_FRAME_INDEX; requestedProperties += PROP_ANIMATION_PLAYING; + requestedProperties += PROP_ANIMATION_SETTINGS; requestedProperties += PROP_TEXTURES; return requestedProperties; @@ -266,6 +270,7 @@ void ModelEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBit APPEND_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, appendValue, getAnimationFrameIndex()); APPEND_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, appendValue, getAnimationIsPlaying()); APPEND_ENTITY_PROPERTY(PROP_TEXTURES, appendValue, getTextures()); + APPEND_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, appendValue, getAnimationSettings()); } diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index aea9407e8b..4a581f2c0a 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -76,6 +76,7 @@ public: void setAnimationURL(const QString& url) { _animationURL = url; } static const float DEFAULT_ANIMATION_FRAME_INDEX; void setAnimationFrameIndex(float value) { _animationLoop.setFrameIndex(value); } + void setAnimationSettings(const QString& value) { _animationSettings = value; } static const bool DEFAULT_ANIMATION_IS_PLAYING; void setAnimationIsPlaying(bool value) { _animationLoop.setRunning(value); } @@ -90,6 +91,7 @@ public: bool getAnimationIsPlaying() const { return _animationLoop.isRunning(); } float getAnimationFrameIndex() const { return _animationLoop.getFrameIndex(); } float getAnimationFPS() const { return _animationLoop.getFPS(); } + const QString& getAnimationSettings() const { return _animationSettings; } static const QString DEFAULT_TEXTURES; const QString& getTextures() const { return _textures; } @@ -109,6 +111,7 @@ protected: quint64 _lastAnimated; QString _animationURL; AnimationLoop _animationLoop; + QString _animationSettings; QString _textures; // used on client side From c9e8c21d8d77d95b9b551a7acd096ef6d08f0862 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 12 Nov 2014 19:23:48 -0800 Subject: [PATCH 10/20] partial work on blending of animation settings --- .../entities/src/EntityItemProperties.cpp | 58 +++++++++++++++++++ libraries/entities/src/EntityItemProperties.h | 4 +- 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index e259c5c982..8c17aeae6b 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -120,6 +121,63 @@ void EntityItemProperties::setSittingPoints(const QVector& sitting } } +void EntityItemProperties::setAnimationSettings(const QString& value) { + // the animations setting is a JSON string that may contain various animation settings. + // if it includes fps, frameIndex, or running, those values will be parsed out and + // will over ride the regular animation settings + + QJsonDocument settingsAsJson = QJsonDocument::fromJson(value.toUtf8()); + QJsonObject settingsAsJsonObject = settingsAsJson.object(); + QVariantMap settingsMap = settingsAsJsonObject.toVariantMap(); + if (settingsMap.contains("fps")) { + float fps = settingsMap["fps"].toFloat(); + setAnimationFPS(fps); + } + + if (settingsMap.contains("frameIndex")) { + float frameIndex = settingsMap["frameIndex"].toFloat(); + setAnimationFrameIndex(frameIndex); + } + + if (settingsMap.contains("running")) { + bool running = settingsMap["running"].toBool(); + setAnimationIsPlaying(running); + } + + _animationSettings = value; + _animationSettingsChanged = true; +} + +/** +QString EntityItemProperties::getAnimationSettings() const { + // the animations setting is a JSON string that may contain various animation settings. + // if it includes fps, frameIndex, or running, those values will be parsed out and + // will over ride the regular animation settings + QString value = _animationSettings; + + QJsonDocument settingsAsJson = QJsonDocument::fromJson(value.toUtf8()); + QJsonObject settingsAsJsonObject = settingsAsJson.object(); + QVariantMap settingsMap = settingsAsJsonObject.toVariantMap(); + if (settingsMap.contains("fps")) { + float fps = settingsMap["fps"].toFloat(); + setAnimationFPS(fps); + } + + if (settingsMap.contains("frameIndex")) { + float frameIndex = settingsMap["frameIndex"].toFloat(); + setAnimationFrameIndex(frameIndex); + } + + if (settingsMap.contains("running")) { + bool running = settingsMap["running"].toBool(); + setAnimationIsPlaying(running); + } + + _animationSettings = value; + _animationSettingsChanged = true; +} +**/ + void EntityItemProperties::debugDump() const { qDebug() << "EntityItemProperties..."; diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 6cc205c1a2..5828a07122 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -192,9 +192,7 @@ public: void setAnimationFrameIndex(float value) { _animationFrameIndex = value; _animationFrameIndexChanged = true; } void setAnimationIsPlaying(bool value) { _animationIsPlaying = value; _animationIsPlayingChanged = true; } void setAnimationFPS(float value) { _animationFPS = value; _animationFPSChanged = true; } - void setAnimationSettings(const QString& value) - { _animationSettings = value; _animationSettingsChanged = true; } - + void setAnimationSettings(const QString& value); void setGlowLevel(float value) { _glowLevel = value; _glowLevelChanged = true; } void setLocalRenderAlpha(float value) { _localRenderAlpha = value; _localRenderAlphaChanged = true; } From e4355cd139582413a1dd8c3359660644bd17919c Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 13 Nov 2014 07:34:54 -0800 Subject: [PATCH 11/20] calculated animationSettings property to include older properties --- .../entities/src/EntityItemProperties.cpp | 38 +++++++++---------- libraries/entities/src/EntityItemProperties.h | 2 +- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 8c17aeae6b..61846d008e 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -148,7 +148,6 @@ void EntityItemProperties::setAnimationSettings(const QString& value) { _animationSettingsChanged = true; } -/** QString EntityItemProperties::getAnimationSettings() const { // the animations setting is a JSON string that may contain various animation settings. // if it includes fps, frameIndex, or running, those values will be parsed out and @@ -158,26 +157,22 @@ QString EntityItemProperties::getAnimationSettings() const { QJsonDocument settingsAsJson = QJsonDocument::fromJson(value.toUtf8()); QJsonObject settingsAsJsonObject = settingsAsJson.object(); QVariantMap settingsMap = settingsAsJsonObject.toVariantMap(); - if (settingsMap.contains("fps")) { - float fps = settingsMap["fps"].toFloat(); - setAnimationFPS(fps); - } - - if (settingsMap.contains("frameIndex")) { - float frameIndex = settingsMap["frameIndex"].toFloat(); - setAnimationFrameIndex(frameIndex); - } - - if (settingsMap.contains("running")) { - bool running = settingsMap["running"].toBool(); - setAnimationIsPlaying(running); - } - _animationSettings = value; - _animationSettingsChanged = true; -} -**/ + QVariant fpsValue(getAnimationFPS()); + settingsMap["fps"] = fpsValue; + QVariant frameIndexValue(getAnimationFrameIndex()); + settingsMap["frameIndex"] = frameIndexValue; + + QVariant runningValue(getAnimationIsPlaying()); + settingsMap["running"] = runningValue; + + settingsAsJsonObject = QJsonObject::fromVariantMap(settingsMap); + QJsonDocument newDocument(settingsAsJsonObject); + QByteArray jsonByteArray = newDocument.toJson(QJsonDocument::Compact); + QString jsonByteString(jsonByteArray); + return jsonByteString; +} void EntityItemProperties::debugDump() const { qDebug() << "EntityItemProperties..."; @@ -265,7 +260,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine) cons COPY_PROPERTY_TO_QSCRIPTVALUE(animationIsPlaying); COPY_PROPERTY_TO_QSCRIPTVALUE(animationFPS); COPY_PROPERTY_TO_QSCRIPTVALUE(animationFrameIndex); - COPY_PROPERTY_TO_QSCRIPTVALUE(animationSettings); + COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(animationSettings,getAnimationSettings()); COPY_PROPERTY_TO_QSCRIPTVALUE(glowLevel); COPY_PROPERTY_TO_QSCRIPTVALUE(localRenderAlpha); COPY_PROPERTY_TO_QSCRIPTVALUE(ignoreForCollisions); @@ -340,6 +335,9 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object) { COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(animationFPS, setAnimationFPS); COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(animationFrameIndex, setAnimationFrameIndex); COPY_PROPERTY_FROM_QSCRIPTVALUE_STRING(animationSettings, setAnimationSettings); + +qDebug() << "_animationSettingsChanged:" << _animationSettingsChanged; + COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(glowLevel, setGlowLevel); COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(localRenderAlpha, setLocalRenderAlpha); COPY_PROPERTY_FROM_QSCRIPTVALUE_BOOL(ignoreForCollisions, setIgnoreForCollisions); diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 5828a07122..d6b8181c28 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -179,7 +179,7 @@ public: float getAnimationFrameIndex() const { return _animationFrameIndex; } bool getAnimationIsPlaying() const { return _animationIsPlaying; } float getAnimationFPS() const { return _animationFPS; } - const QString& getAnimationSettings() const { return _animationSettings; } + QString getAnimationSettings() const; float getGlowLevel() const { return _glowLevel; } float getLocalRenderAlpha() const { return _localRenderAlpha; } From 43f44f4131e4c4ecc588ec7395c4d9f23c19df3d Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 13 Nov 2014 07:52:00 -0800 Subject: [PATCH 12/20] suppress some potentially repeated log messages --- libraries/octree/src/Octree.cpp | 21 +++++++++++++++++++-- libraries/octree/src/OctreeSceneStats.cpp | 7 ++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/libraries/octree/src/Octree.cpp b/libraries/octree/src/Octree.cpp index 596dd7536c..4450689949 100644 --- a/libraries/octree/src/Octree.cpp +++ b/libraries/octree/src/Octree.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -71,6 +72,10 @@ void Octree::recurseTreeWithPostOperation(RecurseOctreeOperation operation, void void Octree::recurseElementWithOperation(OctreeElement* element, RecurseOctreeOperation operation, void* extraData, int recursionCount) { if (recursionCount > DANGEROUSLY_DEEP_RECURSION) { + static QString repeatedMessage + = LogHandler::getInstance().addRepeatedMessageRegex( + "Octree::recurseElementWithOperation() reached DANGEROUSLY_DEEP_RECURSION, bailing!"); + qDebug() << "Octree::recurseElementWithOperation() reached DANGEROUSLY_DEEP_RECURSION, bailing!"; return; } @@ -89,7 +94,11 @@ void Octree::recurseElementWithOperation(OctreeElement* element, RecurseOctreeOp void Octree::recurseElementWithPostOperation(OctreeElement* element, RecurseOctreeOperation operation, void* extraData, int recursionCount) { if (recursionCount > DANGEROUSLY_DEEP_RECURSION) { - qDebug() << "Octree::recurseElementWithOperation() reached DANGEROUSLY_DEEP_RECURSION, bailing!\n"; + static QString repeatedMessage + = LogHandler::getInstance().addRepeatedMessageRegex( + "Octree::recurseElementWithPostOperation() reached DANGEROUSLY_DEEP_RECURSION, bailing!"); + + qDebug() << "Octree::recurseElementWithPostOperation() reached DANGEROUSLY_DEEP_RECURSION, bailing!"; return; } @@ -115,6 +124,10 @@ void Octree::recurseElementWithOperationDistanceSorted(OctreeElement* element, R const glm::vec3& point, void* extraData, int recursionCount) { if (recursionCount > DANGEROUSLY_DEEP_RECURSION) { + static QString repeatedMessage + = LogHandler::getInstance().addRepeatedMessageRegex( + "Octree::recurseElementWithOperationDistanceSorted() reached DANGEROUSLY_DEEP_RECURSION, bailing!"); + qDebug() << "Octree::recurseElementWithOperationDistanceSorted() reached DANGEROUSLY_DEEP_RECURSION, bailing!"; return; } @@ -152,7 +165,11 @@ void Octree::recurseTreeWithOperator(RecurseOctreeOperator* operatorObject) { bool Octree::recurseElementWithOperator(OctreeElement* element, RecurseOctreeOperator* operatorObject, int recursionCount) { if (recursionCount > DANGEROUSLY_DEEP_RECURSION) { - qDebug() << "Octree::recurseElementWithOperation() reached DANGEROUSLY_DEEP_RECURSION, bailing!"; + static QString repeatedMessage + = LogHandler::getInstance().addRepeatedMessageRegex( + "Octree::recurseElementWithOperator() reached DANGEROUSLY_DEEP_RECURSION, bailing!"); + + qDebug() << "Octree::recurseElementWithOperator() reached DANGEROUSLY_DEEP_RECURSION, bailing!"; return false; } diff --git a/libraries/octree/src/OctreeSceneStats.cpp b/libraries/octree/src/OctreeSceneStats.cpp index 82a874a680..4b21890a22 100644 --- a/libraries/octree/src/OctreeSceneStats.cpp +++ b/libraries/octree/src/OctreeSceneStats.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -854,8 +855,12 @@ void OctreeSceneStats::trackIncomingOctreePacket(const QByteArray& packet, const int MAX_RESONABLE_FLIGHT_TIME = 200 * USECS_PER_SECOND; // 200 seconds is more than enough time for a packet to arrive const int MIN_RESONABLE_FLIGHT_TIME = 0; if (flightTime > MAX_RESONABLE_FLIGHT_TIME || flightTime < MIN_RESONABLE_FLIGHT_TIME) { + static QString repeatedMessage + = LogHandler::getInstance().addRepeatedMessageRegex( + "ignoring unreasonable packet... flightTime: -?\\d+ nodeClockSkewUsec: -?\\d+ usecs"); + qDebug() << "ignoring unreasonable packet... flightTime:" << flightTime - << " nodeClockSkewUsec:" << nodeClockSkewUsec << " usecs";; + << "nodeClockSkewUsec:" << nodeClockSkewUsec << "usecs";; return; // ignore any packets that are unreasonable } From ea0022501b67325beda648abc666e47229fd2909 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 13 Nov 2014 08:13:30 -0800 Subject: [PATCH 13/20] only set animation properties if they actually changed --- examples/libraries/entityPropertyDialogBox.js | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/examples/libraries/entityPropertyDialogBox.js b/examples/libraries/entityPropertyDialogBox.js index d4ece08bf4..d0d5add708 100644 --- a/examples/libraries/entityPropertyDialogBox.js +++ b/examples/libraries/entityPropertyDialogBox.js @@ -22,6 +22,8 @@ EntityPropertyDialogBox = (function () { var dimensionZ; var rescalePercentage; var editModelID = -1; + var previousAnimationFrameIndex; + var previousAnimationSettings; that.cleanup = function () { }; @@ -51,8 +53,10 @@ EntityPropertyDialogBox = (function () { array.push({ label: "Animation FPS:", value: properties.animationFPS }); index++; array.push({ label: "Animation Frame:", value: properties.animationFrameIndex }); + previousAnimationFrameIndex = properties.animationFrameIndex; index++; array.push({ label: "Animation Settings:", value: properties.animationSettings }); + previousAnimationSettings = properties.animationSettings; index++; array.push({ label: "Textures:", value: properties.textures }); index++; @@ -241,8 +245,21 @@ EntityPropertyDialogBox = (function () { properties.animationURL = array[index++].value; properties.animationIsPlaying = array[index++].value; properties.animationFPS = array[index++].value; - properties.animationFrameIndex = array[index++].value; - properties.animationSettings = array[index++].value; + + var newAnimationFrameIndex = array[index++].value; + var newAnimationSettings = array[index++].value; + + if (previousAnimationFrameIndex != newAnimationFrameIndex) { + properties.animationFrameIndex = newAnimationFrameIndex; + } else { + delete properties.animationFrameIndex; + } + + if (previousAnimationSettings != newAnimationSettings) { + properties.animationSettings = newAnimationSettings; + } else { + delete properties.animationSettings; + } properties.textures = array[index++].value; index++; // skip textureNames label } From 09a06c9d825dd8ef7b4778a325b20296b512f830 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 13 Nov 2014 08:14:01 -0800 Subject: [PATCH 14/20] add debug streamer for xColor --- libraries/shared/src/SharedUtil.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libraries/shared/src/SharedUtil.h b/libraries/shared/src/SharedUtil.h index ac1b73e50b..69dfb4db35 100644 --- a/libraries/shared/src/SharedUtil.h +++ b/libraries/shared/src/SharedUtil.h @@ -34,6 +34,15 @@ struct xColor { unsigned char blue; }; +inline QDebug& operator<<(QDebug& dbg, const xColor& c) { + dbg.nospace() << "{type='xColor'" + ", red=" << c.red << + ", green=" << c.green << + ", blue=" << c.blue << + "}"; + return dbg; +} + static const float ZERO = 0.0f; static const float ONE = 1.0f; static const float ONE_HALF = 0.5f; From 55c177594bfe6d8f0abcc543dd37505002c5e820 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 13 Nov 2014 08:37:54 -0800 Subject: [PATCH 15/20] only set animationIsPlaying if it changed --- examples/libraries/entityPropertyDialogBox.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/examples/libraries/entityPropertyDialogBox.js b/examples/libraries/entityPropertyDialogBox.js index d0d5add708..da60e0c370 100644 --- a/examples/libraries/entityPropertyDialogBox.js +++ b/examples/libraries/entityPropertyDialogBox.js @@ -22,6 +22,7 @@ EntityPropertyDialogBox = (function () { var dimensionZ; var rescalePercentage; var editModelID = -1; + var previousAnimationIsPlaying; var previousAnimationFrameIndex; var previousAnimationSettings; @@ -49,6 +50,7 @@ EntityPropertyDialogBox = (function () { array.push({ label: "Animation URL:", value: properties.animationURL }); index++; array.push({ label: "Animation is playing:", value: properties.animationIsPlaying }); + previousAnimationIsPlaying = properties.animationIsPlaying; index++; array.push({ label: "Animation FPS:", value: properties.animationFPS }); index++; @@ -243,18 +245,24 @@ EntityPropertyDialogBox = (function () { if (properties.type == "Model") { properties.modelURL = array[index++].value; properties.animationURL = array[index++].value; - properties.animationIsPlaying = array[index++].value; + + var newAnimationIsPlaying = array[index++].value; + if (previousAnimationIsPlaying != newAnimationIsPlaying) { + properties.animationIsPlaying = newAnimationIsPlaying; + } else { + delete properties.animationIsPlaying; + } + properties.animationFPS = array[index++].value; var newAnimationFrameIndex = array[index++].value; - var newAnimationSettings = array[index++].value; - if (previousAnimationFrameIndex != newAnimationFrameIndex) { properties.animationFrameIndex = newAnimationFrameIndex; } else { delete properties.animationFrameIndex; } + var newAnimationSettings = array[index++].value; if (previousAnimationSettings != newAnimationSettings) { properties.animationSettings = newAnimationSettings; } else { From bc60c90308e70fb717d9ce61666cdc6e1d006c61 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 13 Nov 2014 08:39:19 -0800 Subject: [PATCH 16/20] only actually set the properties if they were in the buffer --- libraries/entities/src/ModelEntityItem.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 095b1099b2..ee13ed171b 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -112,9 +112,15 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, animationFrameIndex); READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, animationIsPlaying); - setAnimationIsPlaying(animationIsPlaying); - setAnimationFPS(animationFPS); - setAnimationFrameIndex(animationFrameIndex); + if (propertyFlags.getHasProperty(PROP_ANIMATION_PLAYING)) { + setAnimationIsPlaying(animationIsPlaying); + } + if (propertyFlags.getHasProperty(PROP_ANIMATION_FPS)) { + setAnimationFPS(animationFPS); + } + if (propertyFlags.getHasProperty(PROP_ANIMATION_FRAME_INDEX)) { + setAnimationFrameIndex(animationFrameIndex); + } READ_ENTITY_PROPERTY_STRING(PROP_TEXTURES, setTextures); READ_ENTITY_PROPERTY_STRING(PROP_ANIMATION_SETTINGS, setAnimationSettings); From 701059d7976698a58347af0211ef97fc96e4eb25 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 13 Nov 2014 08:58:33 -0800 Subject: [PATCH 17/20] removed some debug --- libraries/entities/src/EntityItemProperties.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 61846d008e..9e75350bd4 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -335,9 +335,6 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object) { COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(animationFPS, setAnimationFPS); COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(animationFrameIndex, setAnimationFrameIndex); COPY_PROPERTY_FROM_QSCRIPTVALUE_STRING(animationSettings, setAnimationSettings); - -qDebug() << "_animationSettingsChanged:" << _animationSettingsChanged; - COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(glowLevel, setGlowLevel); COPY_PROPERTY_FROM_QSCRIPTVALUE_FLOAT(localRenderAlpha, setLocalRenderAlpha); COPY_PROPERTY_FROM_QSCRIPTVALUE_BOOL(ignoreForCollisions, setIgnoreForCollisions); From 8ec12ea95435952faadb93bf602c4b1c18889272 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 13 Nov 2014 08:59:06 -0800 Subject: [PATCH 18/20] add full animation settings support --- libraries/entities/src/ModelEntityItem.cpp | 93 ++++++++++++++++++++++ libraries/entities/src/ModelEntityItem.h | 19 ++++- 2 files changed, 110 insertions(+), 2 deletions(-) diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index ee13ed171b..d955f22478 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -9,6 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include + #include #include @@ -405,3 +407,94 @@ void ModelEntityItem::debugDump() const { qDebug() << " model URL:" << getModelURL(); } +void ModelEntityItem::setAnimationSettings(const QString& value) { + // the animations setting is a JSON string that may contain various animation settings. + // if it includes fps, frameIndex, or running, those values will be parsed out and + // will over ride the regular animation settings + + QJsonDocument settingsAsJson = QJsonDocument::fromJson(value.toUtf8()); + QJsonObject settingsAsJsonObject = settingsAsJson.object(); + QVariantMap settingsMap = settingsAsJsonObject.toVariantMap(); + if (settingsMap.contains("fps")) { + float fps = settingsMap["fps"].toFloat(); + setAnimationFPS(fps); + } + + if (settingsMap.contains("frameIndex")) { + float frameIndex = settingsMap["frameIndex"].toFloat(); + setAnimationFrameIndex(frameIndex); + } + + if (settingsMap.contains("running")) { + bool running = settingsMap["running"].toBool(); + setAnimationIsPlaying(running); + } + + if (settingsMap.contains("firstFrame")) { + float firstFrame = settingsMap["firstFrame"].toFloat(); + setAnimationFirstFrame(firstFrame); + } + + if (settingsMap.contains("lastFrame")) { + float lastFrame = settingsMap["lastFrame"].toFloat(); + setAnimationLastFrame(lastFrame); + } + + if (settingsMap.contains("loop")) { + bool loop = settingsMap["loop"].toBool(); + setAnimationLoop(loop); + } + + if (settingsMap.contains("hold")) { + bool hold = settingsMap["hold"].toBool(); + setAnimationHold(hold); + } + + if (settingsMap.contains("startAutomatically")) { + bool startAutomatically = settingsMap["startAutomatically"].toBool(); + setAnimationStartAutomatically(startAutomatically); + } + + _animationSettings = value; +} + +QString ModelEntityItem::getAnimationSettings() const { + // the animations setting is a JSON string that may contain various animation settings. + // if it includes fps, frameIndex, or running, those values will be parsed out and + // will over ride the regular animation settings + QString value = _animationSettings; + + QJsonDocument settingsAsJson = QJsonDocument::fromJson(value.toUtf8()); + QJsonObject settingsAsJsonObject = settingsAsJson.object(); + QVariantMap settingsMap = settingsAsJsonObject.toVariantMap(); + + QVariant fpsValue(getAnimationFPS()); + settingsMap["fps"] = fpsValue; + + QVariant frameIndexValue(getAnimationFrameIndex()); + settingsMap["frameIndex"] = frameIndexValue; + + QVariant runningValue(getAnimationIsPlaying()); + settingsMap["running"] = runningValue; + + QVariant firstFrameValue(getAnimationFirstFrame()); + settingsMap["firstFrame"] = firstFrameValue; + + QVariant lastFrameValue(getAnimationLastFrame()); + settingsMap["lastFrame"] = lastFrameValue; + + QVariant loopValue(getAnimationLoop()); + settingsMap["loop"] = loopValue; + + QVariant holdValue(getAnimationHold()); + settingsMap["hold"] = holdValue; + + QVariant startAutomaticallyValue(getAnimationStartAutomatically()); + settingsMap["startAutomatically"] = startAutomaticallyValue; + + settingsAsJsonObject = QJsonObject::fromVariantMap(settingsMap); + QJsonDocument newDocument(settingsAsJsonObject); + QByteArray jsonByteArray = newDocument.toJson(QJsonDocument::Compact); + QString jsonByteString(jsonByteArray); + return jsonByteString; +} diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index 4a581f2c0a..97ffed4076 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -76,13 +76,28 @@ public: void setAnimationURL(const QString& url) { _animationURL = url; } static const float DEFAULT_ANIMATION_FRAME_INDEX; void setAnimationFrameIndex(float value) { _animationLoop.setFrameIndex(value); } - void setAnimationSettings(const QString& value) { _animationSettings = value; } + void setAnimationSettings(const QString& value); static const bool DEFAULT_ANIMATION_IS_PLAYING; void setAnimationIsPlaying(bool value) { _animationLoop.setRunning(value); } static const float DEFAULT_ANIMATION_FPS; void setAnimationFPS(float value) { _animationLoop.setFPS(value); } + + void setAnimationLoop(bool loop) { _animationLoop.setLoop(loop); } + bool getAnimationLoop() const { return _animationLoop.getLoop(); } + + void setAnimationHold(bool hold) { _animationLoop.setHold(hold); } + bool getAnimationHold() const { return _animationLoop.getHold(); } + + void setAnimationStartAutomatically(bool startAutomatically) { _animationLoop.setStartAutomatically(startAutomatically); } + bool getAnimationStartAutomatically() const { return _animationLoop.getStartAutomatically(); } + + void setAnimationFirstFrame(float firstFrame) { _animationLoop.setFirstFrame(firstFrame); } + float getAnimationFirstFrame() const { return _animationLoop.getFirstFrame(); } + + void setAnimationLastFrame(float lastFrame) { _animationLoop.setLastFrame(lastFrame); } + float getAnimationLastFrame() const { return _animationLoop.getLastFrame(); } void mapJoints(const QStringList& modelJointNames); QVector getAnimationFrame(); @@ -91,7 +106,7 @@ public: bool getAnimationIsPlaying() const { return _animationLoop.isRunning(); } float getAnimationFrameIndex() const { return _animationLoop.getFrameIndex(); } float getAnimationFPS() const { return _animationLoop.getFPS(); } - const QString& getAnimationSettings() const { return _animationSettings; } + QString getAnimationSettings() const; static const QString DEFAULT_TEXTURES; const QString& getTextures() const { return _textures; } From 8ad3ce7daf080e0903f6cf61a12bc51786b5e2b9 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 13 Nov 2014 09:32:59 -0800 Subject: [PATCH 19/20] bump packet version --- libraries/networking/src/PacketHeaders.cpp | 2 +- libraries/networking/src/PacketHeaders.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/networking/src/PacketHeaders.cpp b/libraries/networking/src/PacketHeaders.cpp index b5cf84ee28..a5fdd86e3d 100644 --- a/libraries/networking/src/PacketHeaders.cpp +++ b/libraries/networking/src/PacketHeaders.cpp @@ -75,7 +75,7 @@ PacketVersion versionForPacketType(PacketType type) { return 1; case PacketTypeEntityAddOrEdit: case PacketTypeEntityData: - return VERSION_ENTITIES_SUPPORT_DIMENSIONS; + return VERSION_ENTITIES_MODELS_HAVE_ANIMATION_SETTINGS; case PacketTypeEntityErase: return 2; case PacketTypeAudioStreamStats: diff --git a/libraries/networking/src/PacketHeaders.h b/libraries/networking/src/PacketHeaders.h index 2e9ce697f0..466aebd36b 100644 --- a/libraries/networking/src/PacketHeaders.h +++ b/libraries/networking/src/PacketHeaders.h @@ -124,6 +124,7 @@ const PacketVersion VERSION_ROOT_ELEMENT_HAS_DATA = 2; const PacketVersion VERSION_ENTITIES_SUPPORT_SPLIT_MTU = 3; const PacketVersion VERSION_ENTITIES_HAS_FILE_BREAKS = VERSION_ENTITIES_SUPPORT_SPLIT_MTU; const PacketVersion VERSION_ENTITIES_SUPPORT_DIMENSIONS = 4; +const PacketVersion VERSION_ENTITIES_MODELS_HAVE_ANIMATION_SETTINGS = 5; const PacketVersion VERSION_VOXELS_HAS_FILE_BREAKS = 1; #endif // hifi_PacketHeaders_h From 3e521e089b42aac2552cbb1e3354665baf927e2b Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 13 Nov 2014 09:48:15 -0800 Subject: [PATCH 20/20] fix unix build --- libraries/entities/src/EntityItemProperties.cpp | 2 +- libraries/entities/src/ModelEntityItem.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 9e75350bd4..0c184d5e35 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index d955f22478..52b8f7e643 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -9,7 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include +#include #include #include