more correct _created and _lastEdited

This commit is contained in:
Andrew Meadows 2014-12-17 12:38:26 -08:00
parent 5efd996548
commit 8de309a7a9
4 changed files with 59 additions and 60 deletions

View file

@ -53,14 +53,13 @@ void EntityItem::initFromEntityItemID(const EntityItemID& entityItemID) {
_creatorTokenID = entityItemID.creatorTokenID;
// init values with defaults before calling setProperties
//uint64_t now = usecTimestampNow();
_lastEdited = 0;
_lastEditedFromRemote = 0;
_lastEditedFromRemoteInRemoteTime = 0;
_lastSimulated = 0;
_lastUpdated = 0;
_created = 0; // TODO: when do we actually want to make this "now"
_created = usecTimestampNow();
_changedOnServer = 0;
_position = glm::vec3(0,0,0);
@ -100,17 +99,17 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) {
EntityItem::EntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) {
_type = EntityTypes::Unknown;
_lastEdited = 0;
_lastEditedFromRemote = 0;
_lastEditedFromRemoteInRemoteTime = 0;
_lastSimulated = 0;
_lastUpdated = 0;
_created = properties.getCreated();
quint64 now = usecTimestampNow();
_created = properties.getCreated() < now ? properties.getCreated() : now;
_lastEdited = _lastEditedFromRemote = _lastSimulated = _lastUpdated = _lastEditedFromRemoteInRemoteTime = _created;
_physicsInfo = NULL;
_dirtyFlags = 0;
_changedOnServer = 0;
initFromEntityItemID(entityItemID);
setProperties(properties, true); // force copy
if (_lastEdited == 0) {
_lastEdited = _created;
}
}
EntityItem::~EntityItem() {
@ -142,7 +141,6 @@ EntityPropertyFlags EntityItem::getEntityProperties(EncodeBitstreamParams& param
OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packetData, EncodeBitstreamParams& params,
EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData) const {
// ALL this fits...
// object ID [16 bytes]
// ByteCountCoded(type code) [~1 byte]
@ -372,7 +370,10 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
bytesRead += sizeof(createdFromBuffer);
createdFromBuffer -= clockSkew;
_created = createdFromBuffer; // TODO: do we ever want to discard this???
if (createdFromBuffer < _created) {
_created = createdFromBuffer;
_lastEdited = 0;
}
if (wantDebug) {
quint64 lastEdited = getLastEdited();
@ -390,8 +391,6 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
quint64 lastEditedFromBuffer = 0;
quint64 lastEditedFromBufferAdjusted = 0;
// BOOKMARK: TODO: figure out if we can catch remote updates to EntityItems and build a list in the Tree
// that is then relayed to the physics engine (and other data structures that cache EntityItem data)
// TODO: we could make this encoded as a delta from _created
// _lastEdited
memcpy(&lastEditedFromBuffer, dataAt, sizeof(lastEditedFromBuffer));
@ -423,14 +422,14 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
if (fromSameServerEdit) {
// If this is from the same sever packet, then check against any local changes since we got
// the most recent packet from this server time
if (_lastEdited > _lastEditedFromRemote) {
if (_lastEdited >= _lastEditedFromRemote) {
ignoreServerPacket = true;
}
} else {
// If this isn't from the same sever packet, then honor our skew adjusted times...
// If we've changed our local tree more recently than the new data from this packet
// then we will not be changing our values, instead we just read and skip the data
if (_lastEdited > lastEditedFromBufferAdjusted) {
if (_lastEdited >= lastEditedFromBufferAdjusted) {
ignoreServerPacket = true;
}
}
@ -446,7 +445,8 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
qDebug() << "USING NEW data from server!!! ****************";
}
_lastEdited = lastEditedFromBufferAdjusted;
// don't allow _lastEdited to be in the future
_lastEdited = lastEditedFromBufferAdjusted < now ? lastEditedFromBufferAdjusted : now;
_lastEditedFromRemote = now;
_lastEditedFromRemoteInRemoteTime = lastEditedFromBuffer;
@ -783,10 +783,13 @@ bool EntityItem::setProperties(const EntityItemProperties& properties, bool forc
// handle the setting of created timestamps for the basic new entity case
if (forceCopy) {
quint64 now = usecTimestampNow();
if (properties.getCreated() == UNKNOWN_CREATED_TIME) {
_created = usecTimestampNow();
_created = now;
} else if (properties.getCreated() != USE_EXISTING_CREATED_TIME) {
_created = properties.getCreated();
quint64 created = properties.getCreated();
// don't allow _created to be in the future
_created = created < now ? created : now;
}
}
@ -813,13 +816,14 @@ bool EntityItem::setProperties(const EntityItemProperties& properties, bool forc
if (somethingChanged) {
somethingChangedNotification(); // notify derived classes that something has changed
bool wantDebug = false;
uint64_t now = usecTimestampNow();
if (wantDebug) {
uint64_t now = usecTimestampNow();
int elapsed = now - getLastEdited();
qDebug() << "EntityItem::setProperties() AFTER update... edited AGO=" << elapsed <<
"now=" << now << " getLastEdited()=" << getLastEdited();
}
setLastEdited(properties._lastEdited);
// don't allow _lastEdited to be in the future
setLastEdited( properties._lastEdited < now ? properties._lastEdited : now);
if (getDirtyFlags() & EntityItem::DIRTY_POSITION) {
_lastSimulated = usecTimestampNow();
}

View file

@ -95,8 +95,8 @@ enum EntityPropertyList {
typedef PropertyFlags<EntityPropertyList> EntityPropertyFlags;
const quint64 UNKNOWN_CREATED_TIME = (quint64)(-1);
const quint64 USE_EXISTING_CREATED_TIME = (quint64)(-2);
const quint64 UNKNOWN_CREATED_TIME = 0;
const quint64 USE_EXISTING_CREATED_TIME = 1;
/// A collection of properties of an entity item used in the scripting API. Translates between the actual properties of an

View file

@ -71,7 +71,6 @@ bool EntityTypes::registerEntityType(EntityType entityType, const char* name, En
EntityItem* EntityTypes::constructEntityItem(EntityType entityType, const EntityItemID& entityID,
const EntityItemProperties& properties) {
EntityItem* newEntityItem = NULL;
EntityTypeFactory factory = NULL;
if (entityType >= 0 && entityType <= LAST) {
@ -129,7 +128,10 @@ EntityItem* EntityTypes::constructEntityItem(const unsigned char* data, int byte
EntityItemID tempEntityID(actualID);
EntityItemProperties tempProperties;
tempProperties.setCreated(usecTimestampNow()); // this is temporary...
quint64 now = usecTimestampNow();
tempProperties.setCreated(now);
tempProperties.setLastEdited(now);
return constructEntityItem(entityType, tempEntityID, tempProperties);
}

View file

@ -113,65 +113,58 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_
if (_outgoingPacketFlags) {
EntityItemProperties properties = _entity->getProperties();
if (_outgoingPacketFlags == OUTGOING_DIRTY_PHYSICS_FLAGS) {
// all outgoing physics flags are set
// This is the common case: physics engine has changed object position/velocity.
if (_outgoingPacketFlags & EntityItem::DIRTY_POSITION) {
btTransform worldTrans = _body->getWorldTransform();
bulletToGLM(worldTrans.getOrigin(), _sentPosition);
properties.setPosition(_sentPosition + ObjectMotionState::getWorldOffset());
bulletToGLM(worldTrans.getRotation(), _sentRotation);
properties.setRotation(_sentRotation);
}
if (_outgoingPacketFlags & EntityItem::DIRTY_VELOCITY) {
if (_body->isActive()) {
bulletToGLM(_body->getLinearVelocity(), _sentVelocity);
bulletToGLM(_body->getAngularVelocity(), _sentAngularVelocity);
bulletToGLM(_body->getGravity(), _sentAcceleration);
// if the speeds are very small we zero them out
const float MINIMUM_EXTRAPOLATION_SPEED_SQUARED = 4.0e-6f; // 2mm/sec
bool zeroSpeed = (glm::length2(_sentVelocity) < MINIMUM_EXTRAPOLATION_SPEED_SQUARED);
if (zeroSpeed) {
_sentVelocity = glm::vec3(0.0f);
}
const float MINIMUM_EXTRAPOLATION_SPIN_SQUARED = 0.004f; // ~0.01 rotation/sec
bool zeroSpin = glm::length2(_sentAngularVelocity) < MINIMUM_EXTRAPOLATION_SPIN_SQUARED;
if (zeroSpin) {
_sentAngularVelocity = glm::vec3(0.0f);
}
_sentMoving = ! (zeroSpeed && zeroSpin);
} else {
_sentVelocity = _sentAngularVelocity = _sentAcceleration = glm::vec3(0.0f);
_sentVelocity = _sentAngularVelocity = glm::vec3(0.0f);
_sentMoving = false;
}
properties.setVelocity(_sentVelocity);
bulletToGLM(_body->getGravity(), _sentAcceleration);
properties.setGravity(_sentAcceleration);
properties.setAngularVelocity(_sentAngularVelocity);
} else {
// subset of outgoing physics flags are set
// This is an uncommon case: physics engine change collided with incoming external change
// we only send data for flags that haven't been cleared.
if (_outgoingPacketFlags & EntityItem::DIRTY_POSITION) {
btTransform worldTrans = _body->getWorldTransform();
bulletToGLM(worldTrans.getOrigin(), _sentPosition);
properties.setPosition(_sentPosition + ObjectMotionState::getWorldOffset());
bulletToGLM(worldTrans.getRotation(), _sentRotation);
properties.setRotation(_sentRotation);
}
if (_outgoingPacketFlags & EntityItem::DIRTY_VELOCITY) {
if (_body->isActive()) {
bulletToGLM(_body->getLinearVelocity(), _sentVelocity);
bulletToGLM(_body->getAngularVelocity(), _sentAngularVelocity);
bulletToGLM(_body->getGravity(), _sentAcceleration);
} else {
_sentVelocity = _sentAngularVelocity = _sentAcceleration = glm::vec3(0.0f);
}
properties.setVelocity(_sentVelocity);
properties.setAngularVelocity(_sentAngularVelocity);
properties.setGravity(_sentAcceleration);
}
}
// TODO: Figure out what LastEdited is used for...
//properties.setLastEdited(now);
glm::vec3 zero(0.0f);
_sentMoving = !(_sentVelocity == zero && _sentAngularVelocity == zero && _sentAcceleration == zero);
// RELIABLE_SEND_HACK: count number of updates for entities at rest so we can stop sending them after some limit.
if (_sentMoving) {
_numNonMovingUpdates = 0;
} else {
_numNonMovingUpdates++;
}
if (_numNonMovingUpdates <= 1) {
// we only update lastEdited when we're sending new physics data
// (i.e. NOT when we just simulate the positions forward, nore when we resend non-moving data)
quint64 lastSimulated = _entity->getLastSimulated();
_entity->setLastEdited(lastSimulated);
properties.setLastEdited(lastSimulated);
} else {
properties.setLastEdited(_entity->getLastEdited());
}
EntityItemID id(_entity->getID());
EntityEditPacketSender* entityPacketSender = static_cast<EntityEditPacketSender*>(packetSender);