From a56567a3693aa5018d5f27c306a3a285389abe7b Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 13 May 2014 09:27:31 -0700 Subject: [PATCH] add support for adjustable FPS --- examples/placeModelsWithHands.js | 2 +- libraries/models/src/ModelItem.cpp | 228 ++++++++++++------ libraries/models/src/ModelItem.h | 37 +-- .../models/src/ModelsScriptingInterface.h | 5 +- 4 files changed, 176 insertions(+), 96 deletions(-) diff --git a/examples/placeModelsWithHands.js b/examples/placeModelsWithHands.js index bd0915da54..47b4615924 100644 --- a/examples/placeModelsWithHands.js +++ b/examples/placeModelsWithHands.js @@ -231,7 +231,7 @@ function checkControllerSide(whichSide) { if (animationURLs[currentModelURL] !== "") { properties.animationURL = animationURLs[currentModelURL]; - properties.isAnimationPlaying = true; + properties.animationIsPlaying = true; } debugPrint("modelRadius=" +modelRadius); diff --git a/libraries/models/src/ModelItem.cpp b/libraries/models/src/ModelItem.cpp index f9b1092c84..474a6a38a4 100644 --- a/libraries/models/src/ModelItem.cpp +++ b/libraries/models/src/ModelItem.cpp @@ -88,8 +88,9 @@ ModelItem::ModelItem(const ModelItemID& modelItemID, const ModelItemProperties& // animation related _animationURL = MODEL_DEFAULT_ANIMATION_URL; - _isAnimationPlaying = false; - _frameIndex = 0.0f; + _animationIsPlaying = false; + _animationFrameIndex = 0.0f; + _animationFPS = MODEL_DEFAULT_ANIMATION_FPS; _jointMappingCompleted = false; _lastAnimated = now; @@ -121,8 +122,9 @@ void ModelItem::init(glm::vec3 position, float radius, rgbColor color, uint32_t // animation related _animationURL = MODEL_DEFAULT_ANIMATION_URL; - _isAnimationPlaying = false; - _frameIndex = 0.0f; + _animationIsPlaying = false; + _animationFrameIndex = 0.0f; + _animationFPS = MODEL_DEFAULT_ANIMATION_FPS; _jointMappingCompleted = false; _lastAnimated = now; } @@ -175,14 +177,19 @@ bool ModelItem::appendModelData(OctreePacketData* packetData) const { } } - // isAnimationPlaying + // animationIsPlaying if (success) { - success = packetData->appendValue(getIsAnimationPlaying()); + success = packetData->appendValue(getAnimationIsPlaying()); } - // frameIndex + // animationFrameIndex if (success) { - success = packetData->appendValue(getFrameIndex()); + success = packetData->appendValue(getAnimationFrameIndex()); + } + + // animationFPS + if (success) { + success = packetData->appendValue(getAnimationFPS()); } return success; @@ -273,17 +280,24 @@ int ModelItem::readModelDataFromBuffer(const unsigned char* data, int bytesLeftT qDebug() << "readModelDataFromBuffer()... animationURL=" << qPrintable(animationURLString); - // isAnimationPlaying - memcpy(&_isAnimationPlaying, dataAt, sizeof(_isAnimationPlaying)); - dataAt += sizeof(_isAnimationPlaying); - bytesRead += sizeof(_isAnimationPlaying); + // animationIsPlaying + memcpy(&_animationIsPlaying, dataAt, sizeof(_animationIsPlaying)); + dataAt += sizeof(_animationIsPlaying); + bytesRead += sizeof(_animationIsPlaying); - // frameIndex - memcpy(&_frameIndex, dataAt, sizeof(_frameIndex)); - dataAt += sizeof(_frameIndex); - bytesRead += sizeof(_frameIndex); + // animationFrameIndex + memcpy(&_animationFrameIndex, dataAt, sizeof(_animationFrameIndex)); + dataAt += sizeof(_animationFrameIndex); + bytesRead += sizeof(_animationFrameIndex); - qDebug() << "readModelDataFromBuffer()... _frameIndex=" << _frameIndex; + qDebug() << "readModelDataFromBuffer()... _animationFrameIndex=" << _animationFrameIndex; + + // animationFPS + memcpy(&_animationFPS, dataAt, sizeof(_animationFPS)); + dataAt += sizeof(_animationFPS); + bytesRead += sizeof(_animationFPS); + + qDebug() << "readModelDataFromBuffer()... _animationFPS=" << _animationFPS; } else { qDebug() << "readModelDataFromBuffer()... this model didn't have animation details"; @@ -424,22 +438,31 @@ ModelItem ModelItem::fromEditPacket(const unsigned char* data, int length, int& qDebug() << "fromEditPacket()... animationURL=" << qPrintable(tempString); } - // isAnimationPlaying + // animationIsPlaying if (isNewModelItem || ((packetContainsBits & MODEL_PACKET_CONTAINS_ANIMATION_PLAYING) == MODEL_PACKET_CONTAINS_ANIMATION_PLAYING)) { - memcpy(&newModelItem._isAnimationPlaying, dataAt, sizeof(newModelItem._isAnimationPlaying)); - dataAt += sizeof(newModelItem._isAnimationPlaying); - processedBytes += sizeof(newModelItem._isAnimationPlaying); + memcpy(&newModelItem._animationIsPlaying, dataAt, sizeof(newModelItem._animationIsPlaying)); + dataAt += sizeof(newModelItem._animationIsPlaying); + processedBytes += sizeof(newModelItem._animationIsPlaying); } - // frameIndex + // animationFrameIndex if (isNewModelItem || ((packetContainsBits & MODEL_PACKET_CONTAINS_ANIMATION_FRAME) == MODEL_PACKET_CONTAINS_ANIMATION_FRAME)) { - memcpy(&newModelItem._frameIndex, dataAt, sizeof(newModelItem._frameIndex)); - dataAt += sizeof(newModelItem._frameIndex); - processedBytes += sizeof(newModelItem._frameIndex); + memcpy(&newModelItem._animationFrameIndex, dataAt, sizeof(newModelItem._animationFrameIndex)); + dataAt += sizeof(newModelItem._animationFrameIndex); + processedBytes += sizeof(newModelItem._animationFrameIndex); + } + + // animationFPS + if (isNewModelItem || ((packetContainsBits & + MODEL_PACKET_CONTAINS_ANIMATION_FPS) == MODEL_PACKET_CONTAINS_ANIMATION_FPS)) { + + memcpy(&newModelItem._animationFPS, dataAt, sizeof(newModelItem._animationFPS)); + dataAt += sizeof(newModelItem._animationFPS); + processedBytes += sizeof(newModelItem._animationFPS); } const bool wantDebugging = false; @@ -587,29 +610,41 @@ qDebug() << "encodeModelItemEditMessageDetails()... animationURL=" << qPrintable } - // isAnimationPlaying + // animationIsPlaying if (isNewModelItem || ((packetContainsBits & MODEL_PACKET_CONTAINS_ANIMATION_PLAYING) == MODEL_PACKET_CONTAINS_ANIMATION_PLAYING)) { - bool isAnimationPlaying = properties.getIsAnimationPlaying(); - memcpy(copyAt, &isAnimationPlaying, sizeof(isAnimationPlaying)); - copyAt += sizeof(isAnimationPlaying); - sizeOut += sizeof(isAnimationPlaying); + bool animationIsPlaying = properties.getAnimationIsPlaying(); + memcpy(copyAt, &animationIsPlaying, sizeof(animationIsPlaying)); + copyAt += sizeof(animationIsPlaying); + sizeOut += sizeof(animationIsPlaying); -qDebug() << "encodeModelItemEditMessageDetails()... isAnimationPlaying=" << isAnimationPlaying; +qDebug() << "encodeModelItemEditMessageDetails()... animationIsPlaying=" << animationIsPlaying; } - // frameIndex + // animationFrameIndex if (isNewModelItem || ((packetContainsBits & MODEL_PACKET_CONTAINS_ANIMATION_FRAME) == MODEL_PACKET_CONTAINS_ANIMATION_FRAME)) { - float frameIndex = properties.getFrameIndex(); - memcpy(copyAt, &frameIndex, sizeof(frameIndex)); - copyAt += sizeof(frameIndex); - sizeOut += sizeof(frameIndex); + float animationFrameIndex = properties.getAnimationFrameIndex(); + memcpy(copyAt, &animationFrameIndex, sizeof(animationFrameIndex)); + copyAt += sizeof(animationFrameIndex); + sizeOut += sizeof(animationFrameIndex); -qDebug() << "encodeModelItemEditMessageDetails()... frameIndex=" << frameIndex; +qDebug() << "encodeModelItemEditMessageDetails()... animationFrameIndex=" << animationFrameIndex; + } + + // animationFPS + if (isNewModelItem || ((packetContainsBits & + MODEL_PACKET_CONTAINS_ANIMATION_FPS) == MODEL_PACKET_CONTAINS_ANIMATION_FPS)) { + + float animationFPS = properties.getAnimationFPS(); + memcpy(copyAt, &animationFPS, sizeof(animationFPS)); + copyAt += sizeof(animationFPS); + sizeOut += sizeof(animationFPS); + +qDebug() << "encodeModelItemEditMessageDetails()... animationFPS=" << animationFPS; } bool wantDebugging = false; @@ -699,8 +734,8 @@ QVector ModelItem::getAnimationFrame() { if (hasAnimation() && _jointMappingCompleted) { Animation* myAnimation = getAnimation(_animationURL); QVector frames = myAnimation->getFrames(); - int frameIndex = (int)std::floor(_frameIndex) % frames.size(); - QVector rotations = frames[frameIndex].rotations; + int animationFrameIndex = (int)std::floor(_animationFrameIndex) % frames.size(); + QVector rotations = frames[animationFrameIndex].rotations; frameData.resize(_jointMapping.size()); for (int j = 0; j < _jointMapping.size(); j++) { int rotationIndex = _jointMapping[j]; @@ -716,23 +751,29 @@ void ModelItem::update(const quint64& updateTime) { _lastUpdated = updateTime; setShouldDie(getShouldDie()); -//qDebug() << "ModelItem::update() now=" << now; + quint64 now = usecTimestampNow(); // only advance the frame index if we're playing - if (getIsAnimationPlaying()) { + if (getAnimationIsPlaying()) { - quint64 now = usecTimestampNow(); float deltaTime = (float)(now - _lastAnimated) / (float)USECS_PER_SECOND; -qDebug() << "ModelItem::update() now=" << now; -qDebug() << " updateTime=" << updateTime; -qDebug() << " _lastAnimated=" << _lastAnimated; -qDebug() << " deltaTime=" << deltaTime; - + + const bool wantDebugging = false; + if (wantDebugging) { + qDebug() << "ModelItem::update() now=" << now; + qDebug() << " updateTime=" << updateTime; + qDebug() << " _lastAnimated=" << _lastAnimated; + qDebug() << " deltaTime=" << deltaTime; + } _lastAnimated = now; - const float FRAME_RATE = 10.0f; - _frameIndex += deltaTime * FRAME_RATE; -qDebug() << " _frameIndex=" << _frameIndex; + _animationFrameIndex += deltaTime * _animationFPS; + if (wantDebugging) { + qDebug() << " _animationFrameIndex=" << _animationFrameIndex; + } + + } else { + _lastAnimated = now; } } @@ -758,8 +799,9 @@ ModelItemProperties::ModelItemProperties() : _modelURL(""), _modelRotation(MODEL_DEFAULT_MODEL_ROTATION), _animationURL(""), - _isAnimationPlaying(false), - _frameIndex(0.0), + _animationIsPlaying(false), + _animationFrameIndex(0.0), + _animationFPS(MODEL_DEFAULT_ANIMATION_FPS), _id(UNKNOWN_MODEL_ID), _idSet(false), @@ -772,8 +814,9 @@ ModelItemProperties::ModelItemProperties() : _modelURLChanged(false), _modelRotationChanged(false), _animationURLChanged(false), - _isAnimationPlayingChanged(false), - _frameIndexChanged(false), + _animationIsPlayingChanged(false), + _animationFrameIndexChanged(false), + _animationFPSChanged(false), _defaultSettings(true) { } @@ -809,14 +852,18 @@ uint16_t ModelItemProperties::getChangedBits() const { changedBits += MODEL_PACKET_CONTAINS_ANIMATION_URL; } - if (_isAnimationPlayingChanged) { + if (_animationIsPlayingChanged) { changedBits += MODEL_PACKET_CONTAINS_ANIMATION_PLAYING; } - if (_frameIndexChanged) { + if (_animationFrameIndexChanged) { changedBits += MODEL_PACKET_CONTAINS_ANIMATION_FRAME; } + if (_animationFPSChanged) { + changedBits += MODEL_PACKET_CONTAINS_ANIMATION_FPS; + } + return changedBits; } @@ -840,8 +887,9 @@ QScriptValue ModelItemProperties::copyToScriptValue(QScriptEngine* engine) const properties.setProperty("modelRotation", modelRotation); properties.setProperty("animationURL", _animationURL); - properties.setProperty("isAnimationPlaying", _isAnimationPlaying); - properties.setProperty("frameIndex", _frameIndex); + properties.setProperty("animationIsPlaying", _animationIsPlaying); + properties.setProperty("animationFrameIndex", _animationFrameIndex); + properties.setProperty("animationFPS", _animationFPS); if (_idSet) { properties.setProperty("id", _id); @@ -948,23 +996,34 @@ void ModelItemProperties::copyFromScriptValue(const QScriptValue &object) { } } - QScriptValue isAnimationPlaying = object.property("isAnimationPlaying"); - if (isAnimationPlaying.isValid()) { + QScriptValue animationIsPlaying = object.property("animationIsPlaying"); + if (animationIsPlaying.isValid()) { bool newIsAnimationPlaying; - newIsAnimationPlaying = isAnimationPlaying.toVariant().toBool(); - if (_defaultSettings || newIsAnimationPlaying != _isAnimationPlaying) { - _isAnimationPlaying = newIsAnimationPlaying; - _isAnimationPlayingChanged = true; + newIsAnimationPlaying = animationIsPlaying.toVariant().toBool(); + if (_defaultSettings || newIsAnimationPlaying != _animationIsPlaying) { + _animationIsPlaying = newIsAnimationPlaying; + _animationIsPlayingChanged = true; } } - QScriptValue frameIndex = object.property("frameIndex"); - if (frameIndex.isValid()) { + QScriptValue animationFrameIndex = object.property("animationFrameIndex"); + if (animationFrameIndex.isValid()) { float newFrameIndex; - newFrameIndex = frameIndex.toVariant().toFloat(); - if (_defaultSettings || newFrameIndex != _frameIndex) { - _frameIndex = newFrameIndex; - _frameIndexChanged = true; + newFrameIndex = animationFrameIndex.toVariant().toFloat(); + if (_defaultSettings || newFrameIndex != _animationFrameIndex) { + _animationFrameIndex = newFrameIndex; + _animationFrameIndexChanged = true; + } + } + + QScriptValue animationFPS = object.property("animationFPS"); + if (animationFPS.isValid()) { + float newFPS; + newFPS = animationFPS.toVariant().toFloat(); + if (_defaultSettings || newFPS != _animationFPS) { + _animationFPS = newFPS; + _animationFPSChanged = true; +qDebug() << "ModelItemProperties::copyFromScriptValue()... _animationFPS=" << _animationFPS; } } @@ -1010,18 +1069,25 @@ void ModelItemProperties::copyToModelItem(ModelItem& modelItem) const { qDebug() << "ModelItemProperties::copyToModelItem()... modelItem.setAnimationURL(_animationURL)=" << _animationURL; } - if (_isAnimationPlayingChanged) { - modelItem.setIsAnimationPlaying(_isAnimationPlaying); + if (_animationIsPlayingChanged) { + modelItem.setAnimationIsPlaying(_animationIsPlaying); somethingChanged = true; -qDebug() << "ModelItemProperties::copyToModelItem()... _isAnimationPlaying=" << _isAnimationPlaying; +qDebug() << "ModelItemProperties::copyToModelItem()... _animationIsPlaying=" << _animationIsPlaying; } - if (_frameIndexChanged) { - modelItem.setFrameIndex(_frameIndex); + if (_animationFrameIndexChanged) { + modelItem.setAnimationFrameIndex(_animationFrameIndex); somethingChanged = true; -qDebug() << "ModelItemProperties::copyToModelItem()... _frameIndex=" << _frameIndex; +qDebug() << "ModelItemProperties::copyToModelItem()... _animationFrameIndex=" << _animationFrameIndex; + } + + if (_animationFPSChanged) { + modelItem.setAnimationFPS(_animationFPS); + somethingChanged = true; + +qDebug() << "ModelItemProperties::copyToModelItem()... _animationFPS=" << _animationFPS; } if (somethingChanged) { @@ -1044,8 +1110,9 @@ void ModelItemProperties::copyFromModelItem(const ModelItem& modelItem) { _modelURL = modelItem.getModelURL(); _modelRotation = modelItem.getModelRotation(); _animationURL = modelItem.getAnimationURL(); - _isAnimationPlaying = modelItem.getIsAnimationPlaying(); - _frameIndex = modelItem.getFrameIndex(); + _animationIsPlaying = modelItem.getAnimationIsPlaying(); + _animationFrameIndex = modelItem.getAnimationFrameIndex(); + _animationFPS = modelItem.getAnimationFPS(); _id = modelItem.getID(); _idSet = true; @@ -1058,8 +1125,9 @@ void ModelItemProperties::copyFromModelItem(const ModelItem& modelItem) { _modelURLChanged = false; _modelRotationChanged = false; _animationURLChanged = false; - _isAnimationPlayingChanged = false; - _frameIndexChanged = false; + _animationIsPlayingChanged = false; + _animationFrameIndexChanged = false; + _animationFPSChanged = false; _defaultSettings = false; } diff --git a/libraries/models/src/ModelItem.h b/libraries/models/src/ModelItem.h index a6c317d122..18074fbe13 100644 --- a/libraries/models/src/ModelItem.h +++ b/libraries/models/src/ModelItem.h @@ -46,12 +46,14 @@ const uint16_t MODEL_PACKET_CONTAINS_MODEL_ROTATION = 32; const uint16_t MODEL_PACKET_CONTAINS_ANIMATION_URL = 64; const uint16_t MODEL_PACKET_CONTAINS_ANIMATION_PLAYING = 128; const uint16_t MODEL_PACKET_CONTAINS_ANIMATION_FRAME = 256; +const uint16_t MODEL_PACKET_CONTAINS_ANIMATION_FPS = 512; const float MODEL_DEFAULT_RADIUS = 0.1f / TREE_SCALE; const float MINIMUM_MODEL_ELEMENT_SIZE = (1.0f / 100000.0f) / TREE_SCALE; // smallest size container const QString MODEL_DEFAULT_MODEL_URL(""); const glm::quat MODEL_DEFAULT_MODEL_ROTATION; const QString MODEL_DEFAULT_ANIMATION_URL(""); +const float MODEL_DEFAULT_ANIMATION_FPS = 30.0f; const PacketVersion VERSION_MODELS_HAVE_ANIMATION = 1; @@ -77,8 +79,9 @@ public: const QString& getModelURL() const { return _modelURL; } const glm::quat& getModelRotation() const { return _modelRotation; } const QString& getAnimationURL() const { return _animationURL; } - float getFrameIndex() const { return _frameIndex; } - bool getIsAnimationPlaying() const { return _isAnimationPlaying; } + float getAnimationFrameIndex() const { return _animationFrameIndex; } + bool getAnimationIsPlaying() const { return _animationIsPlaying; } + float getAnimationFPS() const { return _animationFPS; } quint64 getLastEdited() const { return _lastEdited; } uint16_t getChangedBits() const; @@ -93,8 +96,9 @@ public: void setModelURL(const QString& url) { _modelURL = url; _modelURLChanged = true; } void setModelRotation(const glm::quat& rotation) { _modelRotation = rotation; _modelRotationChanged = true; } void setAnimationURL(const QString& url) { _animationURL = url; _animationURLChanged = true; } - void setFrameIndex(float value) { _frameIndex = value; _frameIndexChanged = true; } - void setIsAnimationPlaying(bool value) { _isAnimationPlaying = value; _isAnimationPlayingChanged = true; } + void setAnimationFrameIndex(float value) { _animationFrameIndex = value; _animationFrameIndexChanged = true; } + void setAnimationIsPlaying(bool value) { _animationIsPlaying = value; _animationIsPlayingChanged = true; } + void setAnimationFPS(float value) { _animationFPS = value; _animationFPSChanged = true; } /// used by ModelScriptingInterface to return ModelItemProperties for unknown models void setIsUnknownID() { _id = UNKNOWN_MODEL_ID; _idSet = true; } @@ -111,8 +115,9 @@ private: QString _modelURL; glm::quat _modelRotation; QString _animationURL; - bool _isAnimationPlaying; - float _frameIndex; + bool _animationIsPlaying; + float _animationFrameIndex; + float _animationFPS; uint32_t _id; bool _idSet; @@ -126,8 +131,9 @@ private: bool _modelURLChanged; bool _modelRotationChanged; bool _animationURLChanged; - bool _isAnimationPlayingChanged; - bool _frameIndexChanged; + bool _animationIsPlayingChanged; + bool _animationFrameIndexChanged; + bool _animationFPSChanged; bool _defaultSettings; }; Q_DECLARE_METATYPE(ModelItemProperties); @@ -238,8 +244,9 @@ public: void setModelURL(const QString& url) { _modelURL = url; } void setModelRotation(const glm::quat& rotation) { _modelRotation = rotation; } void setAnimationURL(const QString& url) { _animationURL = url; } - void setFrameIndex(float value) { _frameIndex = value; } - void setIsAnimationPlaying(bool value) { _isAnimationPlaying = value; } + void setAnimationFrameIndex(float value) { _animationFrameIndex = value; } + void setAnimationIsPlaying(bool value) { _animationIsPlaying = value; } + void setAnimationFPS(float value) { _animationFPS = value; } void setProperties(const ModelItemProperties& properties); @@ -268,8 +275,9 @@ public: QVector getAnimationFrame(); bool jointsMapped() const { return _jointMappingCompleted; } - bool getIsAnimationPlaying() const { return _isAnimationPlaying; } - float getFrameIndex() const { return _frameIndex; } + bool getAnimationIsPlaying() const { return _animationIsPlaying; } + float getAnimationFrameIndex() const { return _animationFrameIndex; } + float getAnimationFPS() const { return _animationFPS; } protected: glm::vec3 _position; @@ -291,8 +299,9 @@ protected: quint64 _lastAnimated; QString _animationURL; - float _frameIndex; // we keep this as a float and round to int only when we need the exact index - bool _isAnimationPlaying; + float _animationFrameIndex; // we keep this as a float and round to int only when we need the exact index + bool _animationIsPlaying; + float _animationFPS; bool _jointMappingCompleted; QVector _jointMapping; diff --git a/libraries/models/src/ModelsScriptingInterface.h b/libraries/models/src/ModelsScriptingInterface.h index f08ec715a9..8447e5018d 100644 --- a/libraries/models/src/ModelsScriptingInterface.h +++ b/libraries/models/src/ModelsScriptingInterface.h @@ -65,7 +65,10 @@ public slots: /// plays the model animation. ModelItemID playModelAnimation(ModelItemID modelID); - + */ + + + /* /// gets the current frame of the model animation. float getModelAnimationFrame(ModelItemID modelID);