From 3c38a9eb53316e867eadea0ddbec5d766cdbd005 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 23 Jan 2015 13:32:38 -0800 Subject: [PATCH] add last simulated to the protocal --- libraries/entities/src/EntityItem.cpp | 41 ++++++++++++++++++++-- libraries/entities/src/EntityItem.h | 8 +++-- libraries/networking/src/PacketHeaders.cpp | 2 +- libraries/networking/src/PacketHeaders.h | 1 + 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 7e3e982fb8..cb90875c43 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -140,9 +140,17 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet ByteCountCoded typeCoder = getType(); QByteArray encodedType = typeCoder; - quint64 updateDelta = getLastSimulated() <= getLastEdited() ? 0 : getLastSimulated() - getLastEdited(); + // last updated (animations, non-physics changes) + quint64 updateDelta = getLastUpdated() <= getLastEdited() ? 0 : getLastUpdated() - getLastEdited(); ByteCountCoded updateDeltaCoder = updateDelta; QByteArray encodedUpdateDelta = updateDeltaCoder; + + // last simulated (velocity, angular velocity, physics changes) + quint64 simulatedDelta = getLastSimulated() <= getLastEdited() ? 0 : getLastSimulated() - getLastEdited(); + ByteCountCoded simulatedDeltaCoder = simulatedDelta; + QByteArray encodedSimulatedDelta = simulatedDeltaCoder; + + EntityPropertyFlags propertyFlags(PROP_LAST_ITEM); EntityPropertyFlags requestedProperties = getEntityProperties(params); EntityPropertyFlags propertiesDidntFit = requestedProperties; @@ -170,6 +178,7 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet bool successCreatedFits = false; bool successLastEditedFits = false; bool successLastUpdatedFits = false; + bool successLastSimulatedFits = false; bool successPropertyFlagsFits = false; int propertyFlagsOffset = 0; int oldPropertyFlagsLength = 0; @@ -189,8 +198,11 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet if (successLastEditedFits) { successLastUpdatedFits = packetData->appendValue(encodedUpdateDelta); } - if (successLastUpdatedFits) { + successLastSimulatedFits = packetData->appendValue(encodedSimulatedDelta); + } + + if (successLastSimulatedFits) { propertyFlagsOffset = packetData->getUncompressedByteOffset(); encodedPropertyFlags = propertyFlags; oldPropertyFlagsLength = encodedPropertyFlags.length(); @@ -458,6 +470,25 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef encodedUpdateDelta = updateDeltaCoder; // determine true length dataAt += encodedUpdateDelta.size(); bytesRead += encodedUpdateDelta.size(); + + // Newer bitstreams will have a last simulated and a last updated value + if (args.bitstreamVersion >= VERSION_ENTITIES_HAS_LAST_SIMULATED_TIME) { + // last simulated is stored as ByteCountCoded delta from lastEdited + QByteArray encodedSimulatedDelta = originalDataBuffer.mid(bytesRead); // maximum possible size + ByteCountCoded simulatedDeltaCoder = encodedSimulatedDelta; + quint64 simulatedDelta = simulatedDeltaCoder; + if (overwriteLocalData) { + _lastSimulated = lastEditedFromBufferAdjusted + simulatedDelta; // don't adjust for clock skew since we already did that + if (wantDebug) { + qDebug() << "_lastSimulated =" << _lastSimulated; + qDebug() << "_lastEdited=" << _lastEdited; + qDebug() << "lastEditedFromBufferAdjusted=" << lastEditedFromBufferAdjusted; + } + } + encodedSimulatedDelta = simulatedDeltaCoder; // determine true length + dataAt += encodedSimulatedDelta.size(); + bytesRead += encodedSimulatedDelta.size(); + } // Property Flags QByteArray encodedPropertyFlags = originalDataBuffer.mid(bytesRead); // maximum possible size @@ -521,6 +552,12 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef recalculateCollisionShape(); if (overwriteLocalData && (getDirtyFlags() & EntityItem::DIRTY_POSITION)) { + // TODO: Andrew & Brad to discuss -- this probably should not be "now" but instead should be the last + // simulated time from server. The logic should maybe be: the position changed from the server, so the + // position we just set can be thought of as the position at the time it was last simulated by the + // server (clock skew adjusted). By setting it to "now" we are saying that the last position is to be + // considered to be the correct position for "now" which is likely in the future from when it actually + // was at that last known positition. _lastSimulated = now; } } diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index a9a82c5209..c68b638553 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -86,7 +86,7 @@ public: /// Last edited time of this entity universal usecs quint64 getLastEdited() const { return _lastEdited; } void setLastEdited(quint64 lastEdited) - { _lastEdited = _lastUpdated = lastEdited; _changedOnServer = glm::max(lastEdited, _changedOnServer); } + { _lastEdited = _lastUpdated = _lastSimulated = lastEdited; _changedOnServer = glm::max(lastEdited, _changedOnServer); } float getEditedAgo() const /// Elapsed seconds since this entity was last edited { return (float)(usecTimestampNow() - getLastEdited()) / (float)USECS_PER_SECOND; } @@ -125,6 +125,7 @@ public: // perform update virtual void update(const quint64& now) { _lastUpdated = now; } + quint64 getLastUpdated() const { return _lastUpdated; } // perform linear extrapolation for SimpleEntitySimulation void simulate(const quint64& now); @@ -296,9 +297,10 @@ protected: QUuid _id; uint32_t _creatorTokenID; bool _newlyCreated; - quint64 _lastSimulated; // last time this entity called simulate() - quint64 _lastUpdated; // last time this entity called update() + quint64 _lastSimulated; // last time this entity called simulate(), this includes velocity, angular velocity, and physics changes + quint64 _lastUpdated; // last time this entity called update(), this includes animations and non-physics changes quint64 _lastEdited; // last official local or remote edit time + quint64 _lastEditedFromRemote; // last time we received and edit from the server quint64 _lastEditedFromRemoteInRemoteTime; // last time we received and edit from the server (in server-time-frame) quint64 _created; diff --git a/libraries/networking/src/PacketHeaders.cpp b/libraries/networking/src/PacketHeaders.cpp index 110892a106..07228c8351 100644 --- a/libraries/networking/src/PacketHeaders.cpp +++ b/libraries/networking/src/PacketHeaders.cpp @@ -72,7 +72,7 @@ PacketVersion versionForPacketType(PacketType type) { return 1; case PacketTypeEntityAddOrEdit: case PacketTypeEntityData: - return VERSION_ENTITIES_HAVE_USER_DATA; + return VERSION_ENTITIES_HAS_LAST_SIMULATED_TIME; case PacketTypeEntityErase: return 2; case PacketTypeAudioStreamStats: diff --git a/libraries/networking/src/PacketHeaders.h b/libraries/networking/src/PacketHeaders.h index 87d93b931f..f0d21ca9f8 100644 --- a/libraries/networking/src/PacketHeaders.h +++ b/libraries/networking/src/PacketHeaders.h @@ -126,6 +126,7 @@ const PacketVersion VERSION_ENTITIES_HAS_FILE_BREAKS = VERSION_ENTITIES_SUPPORT_ const PacketVersion VERSION_ENTITIES_SUPPORT_DIMENSIONS = 4; const PacketVersion VERSION_ENTITIES_MODELS_HAVE_ANIMATION_SETTINGS = 5; const PacketVersion VERSION_ENTITIES_HAVE_USER_DATA = 6; +const PacketVersion VERSION_ENTITIES_HAS_LAST_SIMULATED_TIME = 7; const PacketVersion VERSION_OCTREE_HAS_FILE_BREAKS = 1; #endif // hifi_PacketHeaders_h