From 01ad010dc9fa597408ca1d4e7c70f1cc7cbfd68d Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 7 Apr 2017 16:07:14 -0700 Subject: [PATCH 01/11] Cherry picking the fix for the new nv driver --- libraries/render-utils/src/LightAmbient.slh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/libraries/render-utils/src/LightAmbient.slh b/libraries/render-utils/src/LightAmbient.slh index 15e23015cb..a82dfd577e 100644 --- a/libraries/render-utils/src/LightAmbient.slh +++ b/libraries/render-utils/src/LightAmbient.slh @@ -82,13 +82,12 @@ void evalLightingAmbient(out vec3 diffuse, out vec3 specular, LightAmbient ambie <@if supportScattering@> - float ambientOcclusion = curvatureAO(lowNormalCurvature.w * 20.0f) * 0.5f; - float ambientOcclusionHF = curvatureAO(midNormalCurvature.w * 8.0f) * 0.5f; - ambientOcclusion = min(ambientOcclusion, ambientOcclusionHF); - - obscurance = min(obscurance, ambientOcclusion); - if (scattering * isScatteringEnabled() > 0.0) { + float ambientOcclusion = curvatureAO(lowNormalCurvature.w * 20.0f) * 0.5f; + float ambientOcclusionHF = curvatureAO(midNormalCurvature.w * 8.0f) * 0.5f; + ambientOcclusion = min(ambientOcclusion, ambientOcclusionHF); + + obscurance = min(obscurance, ambientOcclusion); // Diffuse from ambient diffuse = sphericalHarmonics_evalSphericalLight(getLightAmbientSphere(ambient), lowNormalCurvature.xyz).xyz; From b2f463180df79b9a07a000983968e3f6199c19f7 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 12 Apr 2017 03:44:24 +0200 Subject: [PATCH 02/11] fix teleport cool-in, added missing TARGETTING state and some ESLINT style fixes --- scripts/system/controllers/teleport.js | 63 ++++++++++++++------------ 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/scripts/system/controllers/teleport.js b/scripts/system/controllers/teleport.js index 33c0b3116e..dcbcaeb621 100644 --- a/scripts/system/controllers/teleport.js +++ b/scripts/system/controllers/teleport.js @@ -29,13 +29,13 @@ var COLORS_TELEPORT_SEAT = { red: 255, green: 0, blue: 170 -} +}; var COLORS_TELEPORT_CAN_TELEPORT = { red: 97, green: 247, blue: 255 -} +}; var COLORS_TELEPORT_CANNOT_TELEPORT = { red: 0, @@ -52,7 +52,7 @@ var COLORS_TELEPORT_CANCEL = { var TELEPORT_CANCEL_RANGE = 1; var COOL_IN_DURATION = 500; -const handInfo = { +var handInfo = { right: { controllerInput: Controller.Standard.RightHand }, @@ -80,7 +80,7 @@ function Trigger(hand) { this.down = function() { var down = _this.buttonValue === 1 ? 1.0 : 0.0; - return down + return down; }; } @@ -90,8 +90,9 @@ var ignoredEntities = []; var TELEPORTER_STATES = { IDLE: 'idle', COOL_IN: 'cool_in', + TARGETTING: 'targetting', TARGETTING_INVALID: 'targetting_invalid', -} +}; var TARGET = { NONE: 'none', // Not currently targetting anything @@ -99,7 +100,7 @@ var TARGET = { INVALID: 'invalid', // The current target is invalid (wall, ceiling, etc.) SURFACE: 'surface', // The current target is a valid surface SEAT: 'seat', // The current target is a seat -} +}; function Teleporter() { var _this = this; @@ -114,8 +115,8 @@ function Teleporter() { this.updateConnected = null; this.activeHand = null; - this.telporterMappingInternalName = 'Hifi-Teleporter-Internal-Dev-' + Math.random(); - this.teleportMappingInternal = Controller.newMapping(this.telporterMappingInternalName); + this.teleporterMappingInternalName = 'Hifi-Teleporter-Internal-Dev-' + Math.random(); + this.teleportMappingInternal = Controller.newMapping(this.teleporterMappingInternalName); // Setup overlays this.cancelOverlay = Overlays.addOverlay("model", { @@ -135,11 +136,11 @@ function Teleporter() { }); this.enableMappings = function() { - Controller.enableMapping(this.telporterMappingInternalName); + Controller.enableMapping(this.teleporterMappingInternalName); }; this.disableMappings = function() { - Controller.disableMapping(teleporter.telporterMappingInternalName); + Controller.disableMapping(teleporter.teleporterMappingInternalName); }; this.cleanup = function() { @@ -179,7 +180,7 @@ function Teleporter() { if (_this.state === TELEPORTER_STATES.COOL_IN) { _this.state = TELEPORTER_STATES.TARGETTING; } - }, COOL_IN_DURATION) + }, COOL_IN_DURATION); this.activeHand = hand; this.enableMappings(); @@ -203,13 +204,13 @@ function Teleporter() { }; this.deleteOverlayBeams = function() { - for (key in this.overlayLines) { + for (var key in this.overlayLines) { if (this.overlayLines[key] !== null) { Overlays.deleteOverlay(this.overlayLines[key]); this.overlayLines[key] = null; } } - } + }; this.update = function() { if (_this.state === TELEPORTER_STATES.IDLE) { @@ -272,7 +273,8 @@ function Teleporter() { this.hideCancelOverlay(); this.hideSeatOverlay(); - this.updateLineOverlay(_this.activeHand, pickRay.origin, intersection.intersection, COLORS_TELEPORT_CAN_TELEPORT); + this.updateLineOverlay(_this.activeHand, pickRay.origin, intersection.intersection, + COLORS_TELEPORT_CAN_TELEPORT); this.updateDestinationOverlay(this.targetOverlay, intersection); } } else if (teleportLocationType === TARGET.SEAT) { @@ -284,13 +286,15 @@ function Teleporter() { } - if (((_this.activeHand == 'left' ? leftPad : rightPad).buttonValue === 0) && inTeleportMode === true) { + if (((_this.activeHand === 'left' ? leftPad : rightPad).buttonValue === 0) && inTeleportMode === true) { + // remember the state before we exit teleport mode and set it back to IDLE + var previousState = this.state; this.exitTeleportMode(); this.hideCancelOverlay(); this.hideTargetOverlay(); this.hideSeatOverlay(); - if (teleportLocationType === TARGET.NONE || teleportLocationType === TARGET.INVALID || this.state === TELEPORTER_STATES.COOL_IN) { + if (teleportLocationType === TARGET.NONE || teleportLocationType === TARGET.INVALID || previousState === TELEPORTER_STATES.COOL_IN) { // Do nothing } else if (teleportLocationType === TARGET.SEAT) { Entities.callEntityMethod(intersection.entityID, 'sit'); @@ -321,7 +325,7 @@ function Teleporter() { this.overlayLines[hand] = Overlays.addOverlay("line3d", lineProperties); } else { - var success = Overlays.editOverlay(this.overlayLines[hand], { + Overlays.editOverlay(this.overlayLines[hand], { start: closePoint, end: farPoint, color: color @@ -361,7 +365,7 @@ function Teleporter() { }; } -//related to repositioning the avatar after you teleport +// related to repositioning the avatar after you teleport function getAvatarFootOffset() { var data = getJointData(); var upperLeg, lowerLeg, foot, toe, toeTop; @@ -384,14 +388,14 @@ function getAvatarFootOffset() { var offset = upperLeg + lowerLeg + foot + toe + toeTop; offset = offset / 100; return offset; -}; +} function getJointData() { var allJointData = []; var jointNames = MyAvatar.jointNames; jointNames.forEach(function(joint, index) { var translation = MyAvatar.getJointTranslation(index); - var rotation = MyAvatar.getJointRotation(index) + var rotation = MyAvatar.getJointRotation(index); allJointData.push({ joint: joint, index: index, @@ -401,7 +405,7 @@ function getJointData() { }); return allJointData; -}; +} var leftPad = new ThumbPad('left'); var rightPad = new ThumbPad('right'); @@ -420,7 +424,7 @@ function isMoving() { } else { return false; } -}; +} function parseJSON(json) { try { @@ -433,7 +437,7 @@ function parseJSON(json) { // point that is being intersected with is looked at. If this normal is more // than MAX_ANGLE_FROM_UP_TO_TELEPORT degrees from <0, 1, 0> (straight up), then // you can't teleport there. -const MAX_ANGLE_FROM_UP_TO_TELEPORT = 70; +var MAX_ANGLE_FROM_UP_TO_TELEPORT = 70; function getTeleportTargetType(intersection) { if (!intersection.intersects) { return TARGET.NONE; @@ -465,7 +469,7 @@ function getTeleportTargetType(intersection) { } else { return TARGET.SURFACE; } -}; +} function registerMappings() { mappingName = 'Hifi-Teleporter-Dev-' + Math.random(); @@ -487,7 +491,7 @@ function registerMappings() { if (isMoving() === true) { return; } - teleporter.enterTeleportMode('left') + teleporter.enterTeleportMode('left'); return; }); teleportMapping.from(Controller.Standard.RightPrimaryThumb) @@ -502,10 +506,10 @@ function registerMappings() { return; } - teleporter.enterTeleportMode('right') + teleporter.enterTeleportMode('right'); return; }); -}; +} registerMappings(); @@ -521,7 +525,6 @@ Script.scriptEnding.connect(cleanup); var isDisabled = false; var handleTeleportMessages = function(channel, message, sender) { - var data; if (sender === MyAvatar.sessionUUID) { if (channel === 'Hifi-Teleport-Disabler') { if (message === 'both') { @@ -531,7 +534,7 @@ var handleTeleportMessages = function(channel, message, sender) { isDisabled = 'left'; } if (message === 'right') { - isDisabled = 'right' + isDisabled = 'right'; } if (message === 'none') { isDisabled = false; @@ -545,7 +548,7 @@ var handleTeleportMessages = function(channel, message, sender) { } } } -} +}; Messages.subscribe('Hifi-Teleport-Disabler'); Messages.subscribe('Hifi-Teleport-Ignore-Add'); From 2d1d207c9be1bb3f2f06e3581e21d754bf5ba0a0 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 12 Apr 2017 10:54:28 -0700 Subject: [PATCH 03/11] lol --- interface/src/avatar/Head.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index 4c6aa10d12..282acf6bf5 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -77,7 +77,7 @@ void Head::simulate(float deltaTime, bool isMine) { float audioLoudness = 0.0f; if (_owningAvatar) { - _owningAvatar->getAudioLoudness(); + audioLoudness = _owningAvatar->getAudioLoudness(); } // Update audio trailing average for rendering facial animations From 6cb88c31f35c9557c6ee7a7be3648f21bd31cdcd Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 11 Apr 2017 15:02:27 -0700 Subject: [PATCH 04/11] AvatarMixer sends min updates for out-of-view avatars --- assignment-client/src/avatars/AvatarMixerSlave.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index 05de209e81..c4497a1066 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -325,7 +325,7 @@ void AvatarMixerSlave::broadcastAvatarData(const SharedNodePointer& node) { _stats.overBudgetAvatars++; detail = PALIsOpen ? AvatarData::PALMinimum : AvatarData::NoData; } else if (!isInView) { - detail = PALIsOpen ? AvatarData::PALMinimum : AvatarData::NoData; + detail = PALIsOpen ? AvatarData::PALMinimum : AvatarData::MinimumData; nodeData->incrementAvatarOutOfView(); } else { detail = distribution(generator) < AVATAR_SEND_FULL_UPDATE_RATIO From e751080f640ed06522283cc9fa7c5dee1edb18ca Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 11 Apr 2017 15:03:11 -0700 Subject: [PATCH 05/11] update model transform even when out of view --- interface/src/avatar/SkeletonModel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index d7dd93cedf..0c11fa456d 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -240,8 +240,8 @@ void SkeletonModel::updateAttitude() { // Called by Avatar::simulate after it has set the joint states (fullUpdate true if changed), // but just before head has been simulated. void SkeletonModel::simulate(float deltaTime, bool fullUpdate) { + updateAttitude(); if (fullUpdate) { - updateAttitude(); setBlendshapeCoefficients(_owningAvatar->getHead()->getBlendshapeCoefficients()); Model::simulate(deltaTime, fullUpdate); From eaefa3d3f28ef260b7fe89ffd212cf1dee956d91 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 13 Apr 2017 13:35:59 -0700 Subject: [PATCH 06/11] avatar-mixer resends to avoid stale avatar --- .../src/avatars/AvatarMixerSlave.cpp | 21 ++++++++++++++----- libraries/avatars/src/AvatarData.h | 7 +++---- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index c4497a1066..a4e9b608de 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -175,6 +175,7 @@ void AvatarMixerSlave::broadcastAvatarData(const SharedNodePointer& node) { } }); + const uint64_t MIN_KEEP_ALIVE_PERIOD_FOR_OTHER_AVATAR = (AVATAR_UPDATE_TIMEOUT - 1) * USECS_PER_SECOND; AvatarSharedPointer thisAvatar = nodeData->getAvatarSharedPointer(); ViewFrustum cameraView = nodeData->getViewFrustom(); std::priority_queue sortedAvatars; @@ -262,11 +263,17 @@ void AvatarMixerSlave::broadcastAvatarData(const SharedNodePointer& node) { // have 15 (45hz-30hz) duplicate frames. In this case, the stat // avg_other_av_skips_per_second does report 15. // - // make sure we haven't already sent this data from this sender to this receiver + // make sure we haven't already sent this data from this sender to that receiver // or that somehow we haven't sent if (lastSeqToReceiver == lastSeqFromSender && lastSeqToReceiver != 0) { - ++numAvatarsHeldBack; - shouldIgnore = true; + // don't ignore this avatar if we haven't sent any update for a long while + uint64_t lastBroadcastTime = nodeData->getLastBroadcastTime(avatarNode->getUUID()); + const AvatarMixerClientData* otherNodeData = reinterpret_cast(avatarNode->getLinkedData()); + if (lastBroadcastTime > otherNodeData->getIdentityChangeTimestamp() && + lastBroadcastTime > startIgnoreCalculation - MIN_KEEP_ALIVE_PERIOD_FOR_OTHER_AVATAR) { + ++numAvatarsHeldBack; + shouldIgnore = true; + } } else if (lastSeqFromSender - lastSeqToReceiver > 1) { // this is a skip - we still send the packet but capture the presence of the skip so we see it happening ++numAvatarsWithSkippedFrames; @@ -302,8 +309,12 @@ void AvatarMixerSlave::broadcastAvatarData(const SharedNodePointer& node) { const AvatarMixerClientData* otherNodeData = reinterpret_cast(otherNode->getLinkedData()); // If the time that the mixer sent AVATAR DATA about Avatar B to Avatar A is BEFORE OR EQUAL TO - // the time that Avatar B flagged an IDENTITY DATA change, send IDENTITY DATA about Avatar B to Avatar A. - if (nodeData->getLastBroadcastTime(otherNode->getUUID()) <= otherNodeData->getIdentityChangeTimestamp()) { + // the time that Avatar B flagged an IDENTITY DATA change + // or if no packet of any type has been sent for some time + // send IDENTITY DATA about Avatar B to Avatar A + uint64_t lastBroadcastTime = nodeData->getLastBroadcastTime(otherNode->getUUID()); + if (lastBroadcastTime <= otherNodeData->getIdentityChangeTimestamp() || + startAvatarDataPacking > lastBroadcastTime + MIN_KEEP_ALIVE_PERIOD_FOR_OTHER_AVATAR) { identityBytesSent += sendIdentityPacket(otherNodeData, node); } diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 5ade0c448e..8319eb5249 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -110,6 +110,8 @@ const char LEFT_HAND_POINTING_FLAG = 1; const char RIGHT_HAND_POINTING_FLAG = 2; const char IS_FINGER_POINTING_FLAG = 4; +const qint64 AVATAR_UPDATE_TIMEOUT = 5 * USECS_PER_SECOND; + // AvatarData state flags - we store the details about the packet encoding in the first byte, // before the "header" structure const char AVATARDATA_FLAGS_MINIMUM = 0; @@ -599,10 +601,7 @@ public: } - bool shouldDie() const { - const qint64 AVATAR_SILENCE_THRESHOLD_USECS = 5 * USECS_PER_SECOND; - return _owningAvatarMixer.isNull() || getUsecsSinceLastUpdate() > AVATAR_SILENCE_THRESHOLD_USECS; - } + bool shouldDie() const { return _owningAvatarMixer.isNull() || getUsecsSinceLastUpdate() > AVATAR_UPDATE_TIMEOUT; } static const float OUT_OF_VIEW_PENALTY; From d72f6cf45e9f8f2c8a0d11190453b7901e434763 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 13 Apr 2017 13:37:18 -0700 Subject: [PATCH 07/11] avatar-mixer to send identity packets as 'reliable' --- assignment-client/src/avatars/AvatarMixerSlave.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index a4e9b608de..56c15f7793 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -69,7 +69,7 @@ void AvatarMixerSlave::processIncomingPackets(const SharedNodePointer& node) { int AvatarMixerSlave::sendIdentityPacket(const AvatarMixerClientData* nodeData, const SharedNodePointer& destinationNode) { int bytesSent = 0; QByteArray individualData = nodeData->getConstAvatarData()->identityByteArray(); - auto identityPacket = NLPacket::create(PacketType::AvatarIdentity, individualData.size()); + auto identityPacket = NLPacket::create(PacketType::AvatarIdentity, individualData.size(), true, true); individualData.replace(0, NUM_BYTES_RFC4122_UUID, nodeData->getNodeID().toRfc4122()); // FIXME, this looks suspicious bytesSent += individualData.size(); identityPacket->write(individualData); From 06b9fd6a7e14ca3dd4d87ca2bedc2fbc9fb10321 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 13 Apr 2017 14:55:08 -0700 Subject: [PATCH 08/11] don't keep stale avatars alive --- .../src/avatars/AvatarMixerSlave.cpp | 26 +++++++------------ 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index 56c15f7793..ee3282f82b 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -67,15 +67,13 @@ void AvatarMixerSlave::processIncomingPackets(const SharedNodePointer& node) { int AvatarMixerSlave::sendIdentityPacket(const AvatarMixerClientData* nodeData, const SharedNodePointer& destinationNode) { - int bytesSent = 0; QByteArray individualData = nodeData->getConstAvatarData()->identityByteArray(); - auto identityPacket = NLPacket::create(PacketType::AvatarIdentity, individualData.size(), true, true); individualData.replace(0, NUM_BYTES_RFC4122_UUID, nodeData->getNodeID().toRfc4122()); // FIXME, this looks suspicious - bytesSent += individualData.size(); - identityPacket->write(individualData); - DependencyManager::get()->sendPacket(std::move(identityPacket), *destinationNode); + auto identityPackets = NLPacketList::create(PacketType::AvatarIdentity, QByteArray(), true, true); + identityPackets->write(individualData); + DependencyManager::get()->sendPacketList(std::move(identityPackets), *destinationNode); _stats.numIdentityPackets++; - return bytesSent; + return individualData.size(); } static const int AVATAR_MIXER_BROADCAST_FRAMES_PER_SECOND = 45; @@ -175,7 +173,6 @@ void AvatarMixerSlave::broadcastAvatarData(const SharedNodePointer& node) { } }); - const uint64_t MIN_KEEP_ALIVE_PERIOD_FOR_OTHER_AVATAR = (AVATAR_UPDATE_TIMEOUT - 1) * USECS_PER_SECOND; AvatarSharedPointer thisAvatar = nodeData->getAvatarSharedPointer(); ViewFrustum cameraView = nodeData->getViewFrustom(); std::priority_queue sortedAvatars; @@ -263,17 +260,11 @@ void AvatarMixerSlave::broadcastAvatarData(const SharedNodePointer& node) { // have 15 (45hz-30hz) duplicate frames. In this case, the stat // avg_other_av_skips_per_second does report 15. // - // make sure we haven't already sent this data from this sender to that receiver + // make sure we haven't already sent this data from this sender to this receiver // or that somehow we haven't sent if (lastSeqToReceiver == lastSeqFromSender && lastSeqToReceiver != 0) { - // don't ignore this avatar if we haven't sent any update for a long while - uint64_t lastBroadcastTime = nodeData->getLastBroadcastTime(avatarNode->getUUID()); - const AvatarMixerClientData* otherNodeData = reinterpret_cast(avatarNode->getLinkedData()); - if (lastBroadcastTime > otherNodeData->getIdentityChangeTimestamp() && - lastBroadcastTime > startIgnoreCalculation - MIN_KEEP_ALIVE_PERIOD_FOR_OTHER_AVATAR) { - ++numAvatarsHeldBack; - shouldIgnore = true; - } + ++numAvatarsHeldBack; + shouldIgnore = true; } else if (lastSeqFromSender - lastSeqToReceiver > 1) { // this is a skip - we still send the packet but capture the presence of the skip so we see it happening ++numAvatarsWithSkippedFrames; @@ -312,9 +303,10 @@ void AvatarMixerSlave::broadcastAvatarData(const SharedNodePointer& node) { // the time that Avatar B flagged an IDENTITY DATA change // or if no packet of any type has been sent for some time // send IDENTITY DATA about Avatar B to Avatar A + const uint64_t AVATAR_UPDATE_STALE = AVATAR_UPDATE_TIMEOUT - USECS_PER_SECOND; uint64_t lastBroadcastTime = nodeData->getLastBroadcastTime(otherNode->getUUID()); if (lastBroadcastTime <= otherNodeData->getIdentityChangeTimestamp() || - startAvatarDataPacking > lastBroadcastTime + MIN_KEEP_ALIVE_PERIOD_FOR_OTHER_AVATAR) { + startAvatarDataPacking > lastBroadcastTime + AVATAR_UPDATE_STALE) { identityBytesSent += sendIdentityPacket(otherNodeData, node); } From 6a8ddee8784a7b84280d41baaa33b464542cf76a Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 13 Apr 2017 16:00:11 -0700 Subject: [PATCH 09/11] send keep-alive packets but don't resend identity --- .../src/avatars/AvatarMixerSlave.cpp | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index ee3282f82b..6e3dd150a4 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -263,8 +263,16 @@ void AvatarMixerSlave::broadcastAvatarData(const SharedNodePointer& node) { // make sure we haven't already sent this data from this sender to this receiver // or that somehow we haven't sent if (lastSeqToReceiver == lastSeqFromSender && lastSeqToReceiver != 0) { - ++numAvatarsHeldBack; - shouldIgnore = true; + // don't ignore this avatar if we haven't sent any update for a long while + // in an effort to prevent other interfaces from deleting a stale avatar instance + uint64_t lastBroadcastTime = nodeData->getLastBroadcastTime(avatarNode->getUUID()); + const AvatarMixerClientData* otherNodeData = reinterpret_cast(avatarNode->getLinkedData()); + const uint64_t AVATAR_UPDATE_STALE = AVATAR_UPDATE_TIMEOUT - USECS_PER_SECOND; + if (lastBroadcastTime > otherNodeData->getIdentityChangeTimestamp() && + lastBroadcastTime + AVATAR_UPDATE_STALE > startIgnoreCalculation) { + ++numAvatarsHeldBack; + shouldIgnore = true; + } } else if (lastSeqFromSender - lastSeqToReceiver > 1) { // this is a skip - we still send the packet but capture the presence of the skip so we see it happening ++numAvatarsWithSkippedFrames; @@ -300,13 +308,8 @@ void AvatarMixerSlave::broadcastAvatarData(const SharedNodePointer& node) { const AvatarMixerClientData* otherNodeData = reinterpret_cast(otherNode->getLinkedData()); // If the time that the mixer sent AVATAR DATA about Avatar B to Avatar A is BEFORE OR EQUAL TO - // the time that Avatar B flagged an IDENTITY DATA change - // or if no packet of any type has been sent for some time - // send IDENTITY DATA about Avatar B to Avatar A - const uint64_t AVATAR_UPDATE_STALE = AVATAR_UPDATE_TIMEOUT - USECS_PER_SECOND; - uint64_t lastBroadcastTime = nodeData->getLastBroadcastTime(otherNode->getUUID()); - if (lastBroadcastTime <= otherNodeData->getIdentityChangeTimestamp() || - startAvatarDataPacking > lastBroadcastTime + AVATAR_UPDATE_STALE) { + // the time that Avatar B flagged an IDENTITY DATA change, send IDENTITY DATA about Avatar B to Avatar A. + if (nodeData->getLastBroadcastTime(otherNode->getUUID()) <= otherNodeData->getIdentityChangeTimestamp()) { identityBytesSent += sendIdentityPacket(otherNodeData, node); } From 66137e78a2d4de4094e5001e734fe6cd366aa4d2 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 14 Apr 2017 14:20:04 -0700 Subject: [PATCH 10/11] grab script checks for touch devices continually, rather than just when the script starts --- scripts/system/controllers/handControllerGrab.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index d1c00a9d81..e5271b0e62 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -1051,8 +1051,6 @@ function MyController(hand) { this.homeButtonTouched = false; this.editTriggered = false; - this.controllerJointIndex = getControllerJointIndex(this.hand); - // Until there is some reliable way to keep track of a "stack" of parentIDs, we'll have problems // when more than one avatar does parenting grabs on things. This script tries to work // around this with two associative arrays: previousParentID and previousParentJointIndex. If @@ -1736,6 +1734,7 @@ function MyController(hand) { this.off = function(deltaTime, timestamp) { + this.controllerJointIndex = getControllerJointIndex(this.hand); this.checkForUnexpectedChildren(); if (this.editTriggered) { From d1a11740f07f23ec4b8243ab49b4c543268c949d Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 17 Apr 2017 11:02:27 -0700 Subject: [PATCH 11/11] Whoops --- libraries/avatars/src/AvatarHashMap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/avatars/src/AvatarHashMap.h b/libraries/avatars/src/AvatarHashMap.h index 87bedf8d51..e944c7c887 100644 --- a/libraries/avatars/src/AvatarHashMap.h +++ b/libraries/avatars/src/AvatarHashMap.h @@ -41,7 +41,7 @@ public: Q_INVOKABLE QVector getAvatarIdentifiers(); // Null/Default-constructed QUuids will return MyAvatar - virtual ScriptAvatarData* getAvatar(QUuid avatarID) { return new ScriptAvatarData(getAvatarBySessionID(avatarID)); } + Q_INVOKABLE virtual ScriptAvatarData* getAvatar(QUuid avatarID) { return new ScriptAvatarData(getAvatarBySessionID(avatarID)); } virtual AvatarSharedPointer getAvatarBySessionID(const QUuid& sessionID) const { return findAvatar(sessionID); } int numberOfAvatarsInRange(const glm::vec3& position, float rangeMeters);