Merge pull request #14627 from AndrewMeadows/fewer-avatar-entity-updates

case 20304: please don't flood the avatar-mixer with unnecessary AvatarEntity udpates
This commit is contained in:
John Conklin II 2019-01-09 14:55:23 -08:00 committed by GitHub
commit e4abb66199
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 29 additions and 14 deletions

View file

@ -60,7 +60,6 @@ void addAvatarEntities(const QVariantList& avatarEntities) {
entityProperties.setParentID(myNodeID); entityProperties.setParentID(myNodeID);
entityProperties.setEntityHostType(entity::HostType::AVATAR); entityProperties.setEntityHostType(entity::HostType::AVATAR);
entityProperties.setOwningAvatarID(myNodeID); entityProperties.setOwningAvatarID(myNodeID);
entityProperties.setSimulationOwner(myNodeID, AVATAR_ENTITY_SIMULATION_PRIORITY);
entityProperties.markAllChanged(); entityProperties.markAllChanged();
EntityItemID id = EntityItemID(QUuid::createUuid()); EntityItemID id = EntityItemID(QUuid::createUuid());

View file

@ -27,6 +27,9 @@ Base3DOverlay::Base3DOverlay() :
_drawInFront(false), _drawInFront(false),
_drawHUDLayer(false) _drawHUDLayer(false)
{ {
// HACK: queryAACube stuff not actually relevant for 3DOverlays, and by setting _queryAACubeSet true here
// we can avoid incorrect evaluation for sending updates for entities with 3DOverlays children.
_queryAACubeSet = true;
} }
Base3DOverlay::Base3DOverlay(const Base3DOverlay* base3DOverlay) : Base3DOverlay::Base3DOverlay(const Base3DOverlay* base3DOverlay) :
@ -41,6 +44,9 @@ Base3DOverlay::Base3DOverlay(const Base3DOverlay* base3DOverlay) :
_isVisibleInSecondaryCamera(base3DOverlay->_isVisibleInSecondaryCamera) _isVisibleInSecondaryCamera(base3DOverlay->_isVisibleInSecondaryCamera)
{ {
setTransform(base3DOverlay->getTransform()); setTransform(base3DOverlay->getTransform());
// HACK: queryAACube stuff not actually relevant for 3DOverlays, and by setting _queryAACubeSet true here
// we can avoid incorrect evaluation for sending updates for entities with 3DOverlays children.
_queryAACubeSet = true;
} }
QVariantMap convertOverlayLocationFromScriptSemantics(const QVariantMap& properties, bool scalesWithParent) { QVariantMap convertOverlayLocationFromScriptSemantics(const QVariantMap& properties, bool scalesWithParent) {
@ -209,6 +215,7 @@ void Base3DOverlay::setProperties(const QVariantMap& originalProperties) {
transaction.updateItem(itemID); transaction.updateItem(itemID);
scene->enqueueTransaction(transaction); scene->enqueueTransaction(transaction);
} }
_queryAACubeSet = true; // HACK: just in case some SpatiallyNestable code accidentally set it false
} }
} }

View file

@ -25,6 +25,7 @@ public:
Base3DOverlay(const Base3DOverlay* base3DOverlay); Base3DOverlay(const Base3DOverlay* base3DOverlay);
void setVisible(bool visible) override; void setVisible(bool visible) override;
bool queryAACubeNeedsUpdate() const override { return false; } // HACK: queryAACube not relevant for Overlays
virtual OverlayID getOverlayID() const override { return OverlayID(getID().toString()); } virtual OverlayID getOverlayID() const override { return OverlayID(getID().toString()); }
void setOverlayID(OverlayID overlayID) override { setID(overlayID); } void setOverlayID(OverlayID overlayID) override { setID(overlayID); }

View file

@ -394,10 +394,6 @@ void Avatar::updateAvatarEntities() {
properties.setEntityHostType(entity::HostType::AVATAR); properties.setEntityHostType(entity::HostType::AVATAR);
properties.setOwningAvatarID(getID()); properties.setOwningAvatarID(getID());
// there's no entity-server to tell us we're the simulation owner, so always set the
// simulationOwner to the owningAvatarID and a high priority.
properties.setSimulationOwner(getID(), AVATAR_ENTITY_SIMULATION_PRIORITY);
if (properties.getParentID() == AVATAR_SELF_ID) { if (properties.getParentID() == AVATAR_SELF_ID) {
properties.setParentID(getID()); properties.setParentID(getID());
} }

View file

@ -157,7 +157,7 @@ public:
DEFINE_PROPERTY(PROP_CREATED, Created, created, quint64, UNKNOWN_CREATED_TIME); DEFINE_PROPERTY(PROP_CREATED, Created, created, quint64, UNKNOWN_CREATED_TIME);
DEFINE_PROPERTY_REF(PROP_LAST_EDITED_BY, LastEditedBy, lastEditedBy, QUuid, ENTITY_ITEM_DEFAULT_LAST_EDITED_BY); DEFINE_PROPERTY_REF(PROP_LAST_EDITED_BY, LastEditedBy, lastEditedBy, QUuid, ENTITY_ITEM_DEFAULT_LAST_EDITED_BY);
DEFINE_PROPERTY_REF_ENUM(PROP_ENTITY_HOST_TYPE, EntityHostType, entityHostType, entity::HostType, entity::HostType::DOMAIN); DEFINE_PROPERTY_REF_ENUM(PROP_ENTITY_HOST_TYPE, EntityHostType, entityHostType, entity::HostType, entity::HostType::DOMAIN);
DEFINE_PROPERTY_REF(PROP_OWNING_AVATAR_ID, OwningAvatarID, owningAvatarID, QUuid, UNKNOWN_ENTITY_ID); DEFINE_PROPERTY_REF_WITH_SETTER(PROP_OWNING_AVATAR_ID, OwningAvatarID, owningAvatarID, QUuid, UNKNOWN_ENTITY_ID);
DEFINE_PROPERTY_REF(PROP_PARENT_ID, ParentID, parentID, QUuid, UNKNOWN_ENTITY_ID); DEFINE_PROPERTY_REF(PROP_PARENT_ID, ParentID, parentID, QUuid, UNKNOWN_ENTITY_ID);
DEFINE_PROPERTY_REF(PROP_PARENT_JOINT_INDEX, ParentJointIndex, parentJointIndex, quint16, -1); DEFINE_PROPERTY_REF(PROP_PARENT_JOINT_INDEX, ParentJointIndex, parentJointIndex, quint16, -1);
DEFINE_PROPERTY_REF(PROP_QUERY_AA_CUBE, QueryAACube, queryAACube, AACube, AACube()); DEFINE_PROPERTY_REF(PROP_QUERY_AA_CUBE, QueryAACube, queryAACube, AACube, AACube());
@ -499,6 +499,16 @@ void EntityPropertyInfoFromScriptValue(const QScriptValue& object, EntityPropert
inline void EntityItemProperties::setPosition(const glm::vec3& value) inline void EntityItemProperties::setPosition(const glm::vec3& value)
{ _position = glm::clamp(value, (float)-HALF_TREE_SCALE, (float)HALF_TREE_SCALE); _positionChanged = true; } { _position = glm::clamp(value, (float)-HALF_TREE_SCALE, (float)HALF_TREE_SCALE); _positionChanged = true; }
inline void EntityItemProperties::setOwningAvatarID(const QUuid& id) {
_owningAvatarID = id;
if (!_owningAvatarID.isNull()) {
// for AvatarEntities there's no entity-server to tell us we're the simulation owner,
// so always set the simulationOwner to the owningAvatarID and a high priority.
setSimulationOwner(_owningAvatarID, AVATAR_ENTITY_SIMULATION_PRIORITY);
}
_owningAvatarIDChanged = true;
}
QDebug& operator<<(QDebug& dbg, const EntityPropertyFlags& f); QDebug& operator<<(QDebug& dbg, const EntityPropertyFlags& f);
inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) { inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) {

View file

@ -96,7 +96,7 @@ const uint8_t RECRUIT_SIMULATION_PRIORITY = VOLUNTEER_SIMULATION_PRIORITY + 1;
// When poking objects with scripts an observer will bid at SCRIPT_EDIT priority. // When poking objects with scripts an observer will bid at SCRIPT_EDIT priority.
const uint8_t SCRIPT_GRAB_SIMULATION_PRIORITY = 128; const uint8_t SCRIPT_GRAB_SIMULATION_PRIORITY = 128;
const uint8_t SCRIPT_POKE_SIMULATION_PRIORITY = SCRIPT_GRAB_SIMULATION_PRIORITY - 1; const uint8_t SCRIPT_POKE_SIMULATION_PRIORITY = SCRIPT_GRAB_SIMULATION_PRIORITY - 1;
const uint8_t AVATAR_ENTITY_SIMULATION_PRIORITY = SCRIPT_GRAB_SIMULATION_PRIORITY + 1; const uint8_t AVATAR_ENTITY_SIMULATION_PRIORITY = 255;
// PERSONAL priority (needs a better name) is the level at which a simulation observer owns its own avatar // PERSONAL priority (needs a better name) is the level at which a simulation observer owns its own avatar
// which really just means: things that collide with it will be bid at a priority level one lower // which really just means: things that collide with it will be bid at a priority level one lower

View file

@ -306,6 +306,8 @@ const btCollisionShape* EntityMotionState::computeNewShape() {
return getShapeManager()->getShape(shapeInfo); return getShapeManager()->getShape(shapeInfo);
} }
const uint8_t MAX_NUM_INACTIVE_UPDATES = 20;
bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) { bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) {
// NOTE: this method is only ever called when the entity simulation is locally owned // NOTE: this method is only ever called when the entity simulation is locally owned
DETAILED_PROFILE_RANGE(simulation_physics, "CheckOutOfSync"); DETAILED_PROFILE_RANGE(simulation_physics, "CheckOutOfSync");
@ -315,15 +317,10 @@ bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) {
// TODO: need to be able to detect when logic dictates we *decrease* priority // TODO: need to be able to detect when logic dictates we *decrease* priority
// WIP: print info whenever _bidPriority mismatches what is known to the entity // WIP: print info whenever _bidPriority mismatches what is known to the entity
if (_entity->dynamicDataNeedsTransmit()) {
return true;
}
int numSteps = simulationStep - _lastStep; int numSteps = simulationStep - _lastStep;
float dt = (float)(numSteps) * PHYSICS_ENGINE_FIXED_SUBSTEP; float dt = (float)(numSteps) * PHYSICS_ENGINE_FIXED_SUBSTEP;
if (_numInactiveUpdates > 0) { if (_numInactiveUpdates > 0) {
const uint8_t MAX_NUM_INACTIVE_UPDATES = 20;
if (_numInactiveUpdates > MAX_NUM_INACTIVE_UPDATES) { if (_numInactiveUpdates > MAX_NUM_INACTIVE_UPDATES) {
// clear local ownership (stop sending updates) and let the server clear itself // clear local ownership (stop sending updates) and let the server clear itself
_entity->clearSimulationOwnership(); _entity->clearSimulationOwnership();
@ -451,8 +448,13 @@ void EntityMotionState::updateSendVelocities() {
if (!_body->isKinematicObject()) { if (!_body->isKinematicObject()) {
clearObjectVelocities(); clearObjectVelocities();
} }
// we pretend we sent the inactive update for this object if (_entity->getEntityHostType() == entity::HostType::AVATAR) {
_numInactiveUpdates = 1; // AvatarEntities only ever need to send one update (their updates are sent over a lossless protocol)
// so we set the count to the max to prevent resends
_numInactiveUpdates = MAX_NUM_INACTIVE_UPDATES;
} else {
++_numInactiveUpdates;
}
} else { } else {
glm::vec3 gravity = _entity->getGravity(); glm::vec3 gravity = _entity->getGravity();