From 813c58a1fb23d90a35d82e680ac0dce558510cd9 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Tue, 17 Jul 2018 11:53:55 -0700 Subject: [PATCH 001/545] adding check to see if near grabbing is ready --- .../controllerModules/webSurfaceLaserInput.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js b/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js index a2fe0bfcd4..1706fadbb7 100644 --- a/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js +++ b/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js @@ -42,6 +42,16 @@ Script.include("/~/system/libraries/controllers.js"); return true; } } + nearGrabName = this.hand === RIGHT_HAND ? "RightNearParentingGrabEntity" : "LeftNearParentingGrabEntity"; + nearGrabModule = getEnabledModuleByName(nearGrabName); + if (nearGrabModule) { + return nearGrabModule.isReady(controllerData).active; + } + nearGrabName = this.hand === RIGHT_HAND ? "RightNearActionGrabEntity" : "LeftNearActionGrabEntity"; + nearGrabModule = getEnabledModuleByName(nearGrabName); + if (nearGrabModule) { + return nearGrabModule.isReady(controllerData).active; + } } return false; }; From eb7bde1bfca86eecf2ef8d291313f9dfe61c3603 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Tue, 17 Jul 2018 15:38:56 -0700 Subject: [PATCH 002/545] switching near grab priority to be before web surface laser --- .../highlightNearbyEntities.js | 2 +- .../controllerModules/inEditMode.js | 2 +- .../controllerModules/inVREditMode.js | 2 +- .../controllerModules/nearActionGrabEntity.js | 2 +- .../nearGrabHyperLinkEntity.js | 2 +- .../controllerModules/nearParentGrabEntity.js | 2 +- .../controllerModules/nearTrigger.js | 2 +- .../controllerModules/webSurfaceLaserInput.js | 32 +++++++++++++++++-- 8 files changed, 36 insertions(+), 10 deletions(-) diff --git a/scripts/system/controllers/controllerModules/highlightNearbyEntities.js b/scripts/system/controllers/controllerModules/highlightNearbyEntities.js index bc09ebee7a..3a33082f64 100644 --- a/scripts/system/controllers/controllerModules/highlightNearbyEntities.js +++ b/scripts/system/controllers/controllerModules/highlightNearbyEntities.js @@ -37,7 +37,7 @@ this.highlightedEntities = []; this.parameters = dispatcherUtils.makeDispatcherModuleParameters( - 480, + 120, this.hand === dispatcherUtils.RIGHT_HAND ? ["rightHand"] : ["leftHand"], [], 100); diff --git a/scripts/system/controllers/controllerModules/inEditMode.js b/scripts/system/controllers/controllerModules/inEditMode.js index a724c2037b..0c24e64af7 100644 --- a/scripts/system/controllers/controllerModules/inEditMode.js +++ b/scripts/system/controllers/controllerModules/inEditMode.js @@ -30,7 +30,7 @@ Script.include("/~/system/libraries/utils.js"); this.reticleMaxY; this.parameters = makeDispatcherModuleParameters( - 160, + 200, this.hand === RIGHT_HAND ? ["rightHand", "rightHandEquip", "rightHandTrigger"] : ["leftHand", "leftHandEquip", "leftHandTrigger"], [], 100, diff --git a/scripts/system/controllers/controllerModules/inVREditMode.js b/scripts/system/controllers/controllerModules/inVREditMode.js index 7b78d5e1c4..02863cf935 100644 --- a/scripts/system/controllers/controllerModules/inVREditMode.js +++ b/scripts/system/controllers/controllerModules/inVREditMode.js @@ -21,7 +21,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); this.disableModules = false; var NO_HAND_LASER = -1; // Invalid hand parameter so that default laser is not displayed. this.parameters = makeDispatcherModuleParameters( - 200, // Not too high otherwise the tablet laser doesn't work. + 240, // Not too high otherwise the tablet laser doesn't work. this.hand === RIGHT_HAND ? ["rightHand", "rightHandEquip", "rightHandTrigger"] : ["leftHand", "leftHandEquip", "leftHandTrigger"], diff --git a/scripts/system/controllers/controllerModules/nearActionGrabEntity.js b/scripts/system/controllers/controllerModules/nearActionGrabEntity.js index f528c6f80f..f3574c668f 100644 --- a/scripts/system/controllers/controllerModules/nearActionGrabEntity.js +++ b/scripts/system/controllers/controllerModules/nearActionGrabEntity.js @@ -26,7 +26,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); this.hapticTargetID = null; this.parameters = makeDispatcherModuleParameters( - 500, + 140, this.hand === RIGHT_HAND ? ["rightHand"] : ["leftHand"], [], 100); diff --git a/scripts/system/controllers/controllerModules/nearGrabHyperLinkEntity.js b/scripts/system/controllers/controllerModules/nearGrabHyperLinkEntity.js index 962ae89bb9..366fcd3032 100644 --- a/scripts/system/controllers/controllerModules/nearGrabHyperLinkEntity.js +++ b/scripts/system/controllers/controllerModules/nearGrabHyperLinkEntity.js @@ -21,7 +21,7 @@ this.hyperlink = ""; this.parameters = makeDispatcherModuleParameters( - 485, + 125, this.hand === RIGHT_HAND ? ["rightHand"] : ["leftHand"], [], 100); diff --git a/scripts/system/controllers/controllerModules/nearParentGrabEntity.js b/scripts/system/controllers/controllerModules/nearParentGrabEntity.js index 38334f5523..ea55ee33f9 100644 --- a/scripts/system/controllers/controllerModules/nearParentGrabEntity.js +++ b/scripts/system/controllers/controllerModules/nearParentGrabEntity.js @@ -39,7 +39,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); this.cloneAllowed = true; this.parameters = makeDispatcherModuleParameters( - 500, + 140, this.hand === RIGHT_HAND ? ["rightHand"] : ["leftHand"], [], 100); diff --git a/scripts/system/controllers/controllerModules/nearTrigger.js b/scripts/system/controllers/controllerModules/nearTrigger.js index 6a9cd9fbcd..f1126dedc3 100644 --- a/scripts/system/controllers/controllerModules/nearTrigger.js +++ b/scripts/system/controllers/controllerModules/nearTrigger.js @@ -29,7 +29,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); this.startSent = false; this.parameters = makeDispatcherModuleParameters( - 480, + 120, this.hand === RIGHT_HAND ? ["rightHandTrigger", "rightHand"] : ["leftHandTrigger", "leftHand"], [], 100); diff --git a/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js b/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js index 1706fadbb7..527ba0bd2f 100644 --- a/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js +++ b/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js @@ -22,7 +22,7 @@ Script.include("/~/system/libraries/controllers.js"); this.running = false; this.parameters = makeDispatcherModuleParameters( - 120, + 160, this.hand === RIGHT_HAND ? ["rightHand"] : ["leftHand"], [], 100, @@ -60,6 +60,30 @@ Script.include("/~/system/libraries/controllers.js"); return this.hand === RIGHT_HAND ? leftOverlayLaserInput : rightOverlayLaserInput; }; + this.isPointingAtGrabbableEntity = function(controllerData, triggerPressed) { + // we are searching for an entity that is not a web entity. We want to be able to + // grab a non-web entity if the ray-pick intersects one. + var intersection = controllerData.rayPicks[this.hand]; + if(intersection.type === Picks.INTERSECTED_ENTITY) { + // is pointing at an entity. + var entityProperty = Entities.getEntityProperties(intersection.objectID); + var entityType = entityProperty.type; + var isGrabbable = entityIsGrabbable(entityProperty); + return (isGrabbable && triggerPressed && entityType !== "Web"); + } else if (intersection.type === Picks.INTERSECTED_OVERLAY) { + var objectID = intersection.objectID; + if ((HMD.tabletID && objectID === HMD.tabletID) || + (HMD.tabletScreenID && objectID === HMD.tabletScreenID) || + (HMD.homeButtonID && objectID === HMD.homeButtonID)) { + return true; + } else { + var overlayType = Overlays.getOverlayType(objectID); + return overlayType === "web3d" || triggerPressed; + } + } + return false; + } + this.isPointingAtTriggerable = function(controllerData, triggerPressed) { // allow pointing at tablet, unlocked web entities, or web overlays automatically without pressing trigger, // but for pointing at locked web entities or non-web overlays user must be pressing trigger @@ -113,7 +137,8 @@ Script.include("/~/system/libraries/controllers.js"); var isTriggerPressed = controllerData.triggerValues[this.hand] > TRIGGER_OFF_VALUE && controllerData.triggerValues[this.otherHand] <= TRIGGER_OFF_VALUE; var allowThisModule = !otherModuleRunning || isTriggerPressed; - if (allowThisModule && this.isPointingAtTriggerable(controllerData, isTriggerPressed)) { + if (allowThisModule && this.isPointingAtTriggerable(controllerData, isTriggerPressed)) { + //this.isPointingAtGrabbableEntity(controllerData, isTriggerPressed)) { this.updateAllwaysOn(); if (isTriggerPressed) { this.dominantHandOverride = true; // Override dominant hand. @@ -134,7 +159,8 @@ Script.include("/~/system/libraries/controllers.js"); var allowThisModule = !otherModuleRunning && !grabModuleNeedsToRun; var isTriggerPressed = controllerData.triggerValues[this.hand] > TRIGGER_OFF_VALUE; var laserOn = isTriggerPressed || this.parameters.handLaser.allwaysOn; - if (allowThisModule && (laserOn && this.isPointingAtTriggerable(controllerData, isTriggerPressed))) { + if (allowThisModule && (laserOn && this.isPointingAtTriggerable(controllerData, isTriggerPressed)) && + this.isPointingAtGrabbableEntity(controllerData, isTriggerPressed)) { this.running = true; return makeRunningValues(true, [], []); } From 30ca5a8cbd08a7fb440ea4baaf336c74c7a3e770 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Tue, 17 Jul 2018 16:44:49 -0700 Subject: [PATCH 003/545] code cleanup to use web laser if laser is not pointing at grabbable entity --- .../controllerModules/webSurfaceLaserInput.js | 22 +++++-------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js b/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js index 527ba0bd2f..9e07e125e7 100644 --- a/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js +++ b/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js @@ -64,25 +64,15 @@ Script.include("/~/system/libraries/controllers.js"); // we are searching for an entity that is not a web entity. We want to be able to // grab a non-web entity if the ray-pick intersects one. var intersection = controllerData.rayPicks[this.hand]; - if(intersection.type === Picks.INTERSECTED_ENTITY) { + if (intersection.type === Picks.INTERSECTED_ENTITY) { // is pointing at an entity. var entityProperty = Entities.getEntityProperties(intersection.objectID); var entityType = entityProperty.type; var isGrabbable = entityIsGrabbable(entityProperty); return (isGrabbable && triggerPressed && entityType !== "Web"); - } else if (intersection.type === Picks.INTERSECTED_OVERLAY) { - var objectID = intersection.objectID; - if ((HMD.tabletID && objectID === HMD.tabletID) || - (HMD.tabletScreenID && objectID === HMD.tabletScreenID) || - (HMD.homeButtonID && objectID === HMD.homeButtonID)) { - return true; - } else { - var overlayType = Overlays.getOverlayType(objectID); - return overlayType === "web3d" || triggerPressed; - } } return false; - } + }; this.isPointingAtTriggerable = function(controllerData, triggerPressed) { // allow pointing at tablet, unlocked web entities, or web overlays automatically without pressing trigger, @@ -137,8 +127,8 @@ Script.include("/~/system/libraries/controllers.js"); var isTriggerPressed = controllerData.triggerValues[this.hand] > TRIGGER_OFF_VALUE && controllerData.triggerValues[this.otherHand] <= TRIGGER_OFF_VALUE; var allowThisModule = !otherModuleRunning || isTriggerPressed; - if (allowThisModule && this.isPointingAtTriggerable(controllerData, isTriggerPressed)) { - //this.isPointingAtGrabbableEntity(controllerData, isTriggerPressed)) { + if (allowThisModule && this.isPointingAtTriggerable(controllerData, isTriggerPressed) && + !this.isPointingAtGrabbableEntity(controllerData, isTriggerPressed)) { this.updateAllwaysOn(); if (isTriggerPressed) { this.dominantHandOverride = true; // Override dominant hand. @@ -159,8 +149,8 @@ Script.include("/~/system/libraries/controllers.js"); var allowThisModule = !otherModuleRunning && !grabModuleNeedsToRun; var isTriggerPressed = controllerData.triggerValues[this.hand] > TRIGGER_OFF_VALUE; var laserOn = isTriggerPressed || this.parameters.handLaser.allwaysOn; - if (allowThisModule && (laserOn && this.isPointingAtTriggerable(controllerData, isTriggerPressed)) && - this.isPointingAtGrabbableEntity(controllerData, isTriggerPressed)) { + if (allowThisModule && (laserOn && this.isPointingAtTriggerable(controllerData, isTriggerPressed)) && + !this.isPointingAtGrabbableEntity(controllerData, isTriggerPressed)) { this.running = true; return makeRunningValues(true, [], []); } From 33f9acde67e8ac1a7707e9880c5662de271a3eb1 Mon Sep 17 00:00:00 2001 From: amantley Date: Tue, 17 Jul 2018 17:42:11 -0700 Subject: [PATCH 004/545] latest --- interface/src/avatar/MyAvatar.cpp | 20 +++++++++++++++++++- interface/src/avatar/MyAvatar.h | 2 ++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index d084ca69f9..9eaf42d25d 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -89,9 +89,10 @@ const float MyAvatar::ZOOM_MAX = 25.0f; const float MyAvatar::ZOOM_DEFAULT = 1.5f; const float MIN_SCALE_CHANGED_DELTA = 0.001f; const int MODE_READINGS_RING_BUFFER_SIZE = 500; +const int HEAD_FACING_RING_BUFFER_SIZE = 250; const float CENTIMETERS_PER_METER = 100.0f; -//#define DEBUG_DRAW_HMD_MOVING_AVERAGE +#define DEBUG_DRAW_HMD_MOVING_AVERAGE MyAvatar::MyAvatar(QThread* thread) : Avatar(thread), @@ -112,6 +113,7 @@ MyAvatar::MyAvatar(QThread* thread) : _hmdSensorMatrix(), _hmdSensorOrientation(), _hmdSensorPosition(), + _headFacingBuffer(HEAD_FACING_RING_BUFFER_SIZE), _recentModeReadings(MODE_READINGS_RING_BUFFER_SIZE), _bodySensorMatrix(), _goToPending(false), @@ -434,11 +436,25 @@ void MyAvatar::update(float deltaTime) { _recentModeReadings.insert(newHeightReadingInCentimeters); setCurrentStandingHeight(computeStandingHeightMode(getControllerPoseInAvatarFrame(controller::Action::HEAD))); setAverageHeadRotation(computeAverageHeadRotation(getControllerPoseInAvatarFrame(controller::Action::HEAD))); + + glm::vec2 bodyFacing = getFacingDir2D(_bodySensorMatrix); + _headFacingBuffer.insert(_headControllerFacing); + //qCDebug(interfaceapp) << "the body facing is " << -bodyFacing.x << " " << -bodyFacing.y << " the head controller facing is " << _headControllerFacing.x << " " << _headControllerFacing.y; + + float sumHeadFacingX = 0.0f; + float sumHeadFacingY = 0.0f; + for (auto headFacingIterator = _headFacingBuffer.begin(); headFacingIterator != _headFacingBuffer.end(); ++headFacingIterator) { + sumHeadFacingX += (*headFacingIterator).x; + sumHeadFacingY += (*headFacingIterator).y; + } + _averageFacing.x = sumHeadFacingX / (float)_headFacingBuffer.getNumEntries(); + _averageFacing.y= sumHeadFacingY / (float)_headFacingBuffer.getNumEntries(); #ifdef DEBUG_DRAW_HMD_MOVING_AVERAGE auto sensorHeadPose = getControllerPoseInSensorFrame(controller::Action::HEAD); glm::vec3 worldHeadPos = transformPoint(getSensorToWorldMatrix(), sensorHeadPose.getTranslation()); glm::vec3 worldFacingAverage = transformVectorFast(getSensorToWorldMatrix(), glm::vec3(_headControllerFacingMovingAverage.x, 0.0f, _headControllerFacingMovingAverage.y)); + //glm::vec3 worldFacingAverage = transformVectorFast(getSensorToWorldMatrix(), glm::vec3(_averageFacing.x, 0.0f, _averageFacing.y)); glm::vec3 worldFacing = transformVectorFast(getSensorToWorldMatrix(), glm::vec3(_headControllerFacing.x, 0.0f, _headControllerFacing.y)); DebugDraw::getInstance().drawRay(worldHeadPos, worldHeadPos + worldFacing, glm::vec4(0.0f, 1.0f, 0.0f, 1.0f)); DebugDraw::getInstance().drawRay(worldHeadPos, worldHeadPos + worldFacingAverage, glm::vec4(0.0f, 0.0f, 1.0f, 1.0f)); @@ -3478,6 +3494,8 @@ bool MyAvatar::FollowHelper::shouldActivateRotation(const MyAvatar& myAvatar, co const float FOLLOW_ROTATION_THRESHOLD = cosf(myAvatar.getRotationThreshold()); glm::vec2 bodyFacing = getFacingDir2D(currentBodyMatrix); return glm::dot(-myAvatar.getHeadControllerFacingMovingAverage(), bodyFacing) < FOLLOW_ROTATION_THRESHOLD; + + //return glm::dot(myAvatar._averageFacing, -bodyFacing) < FOLLOW_ROTATION_THRESHOLD; } bool MyAvatar::FollowHelper::shouldActivateHorizontal(const MyAvatar& myAvatar, const glm::mat4& desiredBodyMatrix, const glm::mat4& currentBodyMatrix) const { diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 819d5b0066..828ca48e32 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -1546,6 +1546,8 @@ private: // cache head controller pose in sensor space glm::vec2 _headControllerFacing; // facing vector in xz plane (sensor space) glm::vec2 _headControllerFacingMovingAverage { 0.0f, 0.0f }; // facing vector in xz plane (sensor space) + RingBufferHistory _headFacingBuffer; + vec2 _averageFacing { 0.0f, 0.0f }; glm::quat _averageHeadRotation { 0.0f, 0.0f, 0.0f, 1.0f }; float _currentStandingHeight { 0.0f }; From ac642f126a02ebb66303fee75f8dc3bf7ff06922 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Tue, 17 Jul 2018 20:52:50 -0700 Subject: [PATCH 005/545] adding extra conditional to ensure all modules are checked --- .../controllers/controllerModules/webSurfaceLaserInput.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js b/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js index 9e07e125e7..03c8a65637 100644 --- a/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js +++ b/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js @@ -44,12 +44,12 @@ Script.include("/~/system/libraries/controllers.js"); } nearGrabName = this.hand === RIGHT_HAND ? "RightNearParentingGrabEntity" : "LeftNearParentingGrabEntity"; nearGrabModule = getEnabledModuleByName(nearGrabName); - if (nearGrabModule) { + if (nearGrabModule && nearGrabModule.isReady(controllerData)) { return nearGrabModule.isReady(controllerData).active; } nearGrabName = this.hand === RIGHT_HAND ? "RightNearActionGrabEntity" : "LeftNearActionGrabEntity"; nearGrabModule = getEnabledModuleByName(nearGrabName); - if (nearGrabModule) { + if (nearGrabModule && nearGrabModule.isReady(controllerData)) { return nearGrabModule.isReady(controllerData).active; } } From 7cc724a27bf59709be09e9dc4f48ed0ffcd11eb2 Mon Sep 17 00:00:00 2001 From: amantley Date: Wed, 18 Jul 2018 17:08:04 -0700 Subject: [PATCH 006/545] added properties to allow the toggling of the debug draw the look at vector, and the reset moving average look at on step detection --- interface/src/avatar/MyAvatar.cpp | 22 +++++++++++++++------- interface/src/avatar/MyAvatar.h | 8 ++++++++ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 1b9eed9187..63a26fb2ad 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -471,13 +471,15 @@ void MyAvatar::update(float deltaTime) { _averageFacing.y= sumHeadFacingY / (float)_headFacingBuffer.getNumEntries(); #ifdef DEBUG_DRAW_HMD_MOVING_AVERAGE - auto sensorHeadPose = getControllerPoseInSensorFrame(controller::Action::HEAD); - glm::vec3 worldHeadPos = transformPoint(getSensorToWorldMatrix(), sensorHeadPose.getTranslation()); - glm::vec3 worldFacingAverage = transformVectorFast(getSensorToWorldMatrix(), glm::vec3(_headControllerFacingMovingAverage.x, 0.0f, _headControllerFacingMovingAverage.y)); - //glm::vec3 worldFacingAverage = transformVectorFast(getSensorToWorldMatrix(), glm::vec3(_averageFacing.x, 0.0f, _averageFacing.y)); - glm::vec3 worldFacing = transformVectorFast(getSensorToWorldMatrix(), glm::vec3(_headControllerFacing.x, 0.0f, _headControllerFacing.y)); - DebugDraw::getInstance().drawRay(worldHeadPos, worldHeadPos + worldFacing, glm::vec4(0.0f, 1.0f, 0.0f, 1.0f)); - DebugDraw::getInstance().drawRay(worldHeadPos, worldHeadPos + worldFacingAverage, glm::vec4(0.0f, 0.0f, 1.0f, 1.0f)); + if (_drawAverageFacingEnabled) { + auto sensorHeadPose = getControllerPoseInSensorFrame(controller::Action::HEAD); + glm::vec3 worldHeadPos = transformPoint(getSensorToWorldMatrix(), sensorHeadPose.getTranslation()); + glm::vec3 worldFacingAverage = transformVectorFast(getSensorToWorldMatrix(), glm::vec3(_headControllerFacingMovingAverage.x, 0.0f, _headControllerFacingMovingAverage.y)); + //glm::vec3 worldFacingAverage = transformVectorFast(getSensorToWorldMatrix(), glm::vec3(_averageFacing.x, 0.0f, _averageFacing.y)); + glm::vec3 worldFacing = transformVectorFast(getSensorToWorldMatrix(), glm::vec3(_headControllerFacing.x, 0.0f, _headControllerFacing.y)); + DebugDraw::getInstance().drawRay(worldHeadPos, worldHeadPos + worldFacing, glm::vec4(0.0f, 1.0f, 0.0f, 1.0f)); + DebugDraw::getInstance().drawRay(worldHeadPos, worldHeadPos + worldFacingAverage, glm::vec4(0.0f, 0.0f, 1.0f, 1.0f)); + } #endif if (_goToPending) { @@ -3594,10 +3596,16 @@ void MyAvatar::FollowHelper::prePhysicsUpdate(MyAvatar& myAvatar, const glm::mat if (myAvatar.getCenterOfGravityModelEnabled()) { if (!isActive(Horizontal) && (shouldActivateHorizontalCG(myAvatar) || hasDriveInput)) { activate(Horizontal); + if (myAvatar.getEnableStepResetRotation()) { + myAvatar.setHeadControllerFacingMovingAverage(myAvatar._headControllerFacing); + } } } else { if (!isActive(Horizontal) && (shouldActivateHorizontal(myAvatar, desiredBodyMatrix, currentBodyMatrix) || hasDriveInput)) { activate(Horizontal); + if (myAvatar.getEnableStepResetRotation()) { + myAvatar.setHeadControllerFacingMovingAverage(myAvatar._headControllerFacing); + } } } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 0a40ac471c..c0f0166e49 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -198,6 +198,8 @@ class MyAvatar : public Avatar { Q_PROPERTY(bool hasAudioEnabledFaceMovement READ getHasAudioEnabledFaceMovement WRITE setHasAudioEnabledFaceMovement) Q_PROPERTY(float rotationRecenterFilterLength READ getRotationRecenterFilterLength WRITE setRotationRecenterFilterLength) Q_PROPERTY(float rotationThreshold READ getRotationThreshold WRITE setRotationThreshold) + Q_PROPERTY(bool enableStepResetRotation READ getEnableStepResetRotation WRITE setEnableStepResetRotation) + Q_PROPERTY(bool enableDrawAverageFacing READ getEnableDrawAverageFacing WRITE setEnableDrawAverageFacing) //TODO: make gravity feature work Q_PROPERTY(glm::vec3 gravity READ getGravity WRITE setGravity) Q_PROPERTY(glm::vec3 leftHandPosition READ getLeftHandPosition) @@ -1464,6 +1466,10 @@ private: float getRotationRecenterFilterLength() const { return _rotationRecenterFilterLength; } void setRotationThreshold(float angleRadians); float getRotationThreshold() const { return _rotationThreshold; } + void setEnableStepResetRotation(bool stepReset) { _stepResetRotationEnabled = stepReset; } + bool getEnableStepResetRotation() const { return _stepResetRotationEnabled; } + void setEnableDrawAverageFacing(bool drawAverage) { _drawAverageFacingEnabled = drawAverage; } + bool getEnableDrawAverageFacing() const { return _drawAverageFacingEnabled; } bool isMyAvatar() const override { return true; } virtual int parseDataFromBuffer(const QByteArray& buffer) override; virtual glm::vec3 getSkeletonPosition() const override; @@ -1574,6 +1580,8 @@ private: std::atomic _hasScriptedBlendShapes { false }; std::atomic _rotationRecenterFilterLength { 4.0f }; std::atomic _rotationThreshold { 0.5235f }; // 30 degrees in radians + std::atomic _stepResetRotationEnabled { false }; + std::atomic _drawAverageFacingEnabled { false }; // working copy -- see AvatarData for thread-safe _sensorToWorldMatrixCache, used for outward facing access glm::mat4 _sensorToWorldMatrix { glm::mat4() }; From a8c4f4e6507913a8fde6fce37f14418f4a11027c Mon Sep 17 00:00:00 2001 From: amantley Date: Wed, 18 Jul 2018 17:10:09 -0700 Subject: [PATCH 007/545] removed extra whitespace --- interface/src/avatar/MyAvatar.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 63a26fb2ad..34d5017c50 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -456,11 +456,11 @@ void MyAvatar::update(float deltaTime) { _recentModeReadings.insert(newHeightReadingInCentimeters); setCurrentStandingHeight(computeStandingHeightMode(getControllerPoseInAvatarFrame(controller::Action::HEAD))); setAverageHeadRotation(computeAverageHeadRotation(getControllerPoseInAvatarFrame(controller::Action::HEAD))); - + glm::vec2 bodyFacing = getFacingDir2D(_bodySensorMatrix); _headFacingBuffer.insert(_headControllerFacing); //qCDebug(interfaceapp) << "the body facing is " << -bodyFacing.x << " " << -bodyFacing.y << " the head controller facing is " << _headControllerFacing.x << " " << _headControllerFacing.y; - + float sumHeadFacingX = 0.0f; float sumHeadFacingY = 0.0f; for (auto headFacingIterator = _headFacingBuffer.begin(); headFacingIterator != _headFacingBuffer.end(); ++headFacingIterator) { From 5ec7ab3a7d10f50eaefd4638852d68af8b365d6b Mon Sep 17 00:00:00 2001 From: amantley Date: Wed, 18 Jul 2018 17:20:47 -0700 Subject: [PATCH 008/545] removed the other way of computing the average lookat which used a ring buffer --- interface/src/avatar/MyAvatar.cpp | 17 +---------------- interface/src/avatar/MyAvatar.h | 2 -- 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 34d5017c50..10e38afbe3 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -89,7 +89,6 @@ const float MyAvatar::ZOOM_MAX = 25.0f; const float MyAvatar::ZOOM_DEFAULT = 1.5f; const float MIN_SCALE_CHANGED_DELTA = 0.001f; const int MODE_READINGS_RING_BUFFER_SIZE = 500; -const int HEAD_FACING_RING_BUFFER_SIZE = 250; const float CENTIMETERS_PER_METER = 100.0f; #define DEBUG_DRAW_HMD_MOVING_AVERAGE @@ -113,7 +112,6 @@ MyAvatar::MyAvatar(QThread* thread) : _hmdSensorMatrix(), _hmdSensorOrientation(), _hmdSensorPosition(), - _headFacingBuffer(HEAD_FACING_RING_BUFFER_SIZE), _recentModeReadings(MODE_READINGS_RING_BUFFER_SIZE), _bodySensorMatrix(), _goToPending(false), @@ -457,25 +455,14 @@ void MyAvatar::update(float deltaTime) { setCurrentStandingHeight(computeStandingHeightMode(getControllerPoseInAvatarFrame(controller::Action::HEAD))); setAverageHeadRotation(computeAverageHeadRotation(getControllerPoseInAvatarFrame(controller::Action::HEAD))); - glm::vec2 bodyFacing = getFacingDir2D(_bodySensorMatrix); - _headFacingBuffer.insert(_headControllerFacing); - //qCDebug(interfaceapp) << "the body facing is " << -bodyFacing.x << " " << -bodyFacing.y << " the head controller facing is " << _headControllerFacing.x << " " << _headControllerFacing.y; - float sumHeadFacingX = 0.0f; - float sumHeadFacingY = 0.0f; - for (auto headFacingIterator = _headFacingBuffer.begin(); headFacingIterator != _headFacingBuffer.end(); ++headFacingIterator) { - sumHeadFacingX += (*headFacingIterator).x; - sumHeadFacingY += (*headFacingIterator).y; - } - _averageFacing.x = sumHeadFacingX / (float)_headFacingBuffer.getNumEntries(); - _averageFacing.y= sumHeadFacingY / (float)_headFacingBuffer.getNumEntries(); + #ifdef DEBUG_DRAW_HMD_MOVING_AVERAGE if (_drawAverageFacingEnabled) { auto sensorHeadPose = getControllerPoseInSensorFrame(controller::Action::HEAD); glm::vec3 worldHeadPos = transformPoint(getSensorToWorldMatrix(), sensorHeadPose.getTranslation()); glm::vec3 worldFacingAverage = transformVectorFast(getSensorToWorldMatrix(), glm::vec3(_headControllerFacingMovingAverage.x, 0.0f, _headControllerFacingMovingAverage.y)); - //glm::vec3 worldFacingAverage = transformVectorFast(getSensorToWorldMatrix(), glm::vec3(_averageFacing.x, 0.0f, _averageFacing.y)); glm::vec3 worldFacing = transformVectorFast(getSensorToWorldMatrix(), glm::vec3(_headControllerFacing.x, 0.0f, _headControllerFacing.y)); DebugDraw::getInstance().drawRay(worldHeadPos, worldHeadPos + worldFacing, glm::vec4(0.0f, 1.0f, 0.0f, 1.0f)); DebugDraw::getInstance().drawRay(worldHeadPos, worldHeadPos + worldFacingAverage, glm::vec4(0.0f, 0.0f, 1.0f, 1.0f)); @@ -3516,8 +3503,6 @@ bool MyAvatar::FollowHelper::shouldActivateRotation(const MyAvatar& myAvatar, co const float FOLLOW_ROTATION_THRESHOLD = cosf(myAvatar.getRotationThreshold()); glm::vec2 bodyFacing = getFacingDir2D(currentBodyMatrix); return glm::dot(-myAvatar.getHeadControllerFacingMovingAverage(), bodyFacing) < FOLLOW_ROTATION_THRESHOLD; - - //return glm::dot(myAvatar._averageFacing, -bodyFacing) < FOLLOW_ROTATION_THRESHOLD; } bool MyAvatar::FollowHelper::shouldActivateHorizontal(const MyAvatar& myAvatar, const glm::mat4& desiredBodyMatrix, const glm::mat4& currentBodyMatrix) const { diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index c0f0166e49..81315900a7 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -1593,8 +1593,6 @@ private: // cache head controller pose in sensor space glm::vec2 _headControllerFacing; // facing vector in xz plane (sensor space) glm::vec2 _headControllerFacingMovingAverage { 0.0f, 0.0f }; // facing vector in xz plane (sensor space) - RingBufferHistory _headFacingBuffer; - vec2 _averageFacing { 0.0f, 0.0f }; glm::quat _averageHeadRotation { 0.0f, 0.0f, 0.0f, 1.0f }; float _currentStandingHeight { 0.0f }; From 5276d84aa5ccbb75f19f640cf60af794dba7d516 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Thu, 19 Jul 2018 17:08:12 -0700 Subject: [PATCH 009/545] pushing what i coded out loud - it broke the way grabbing works --- .../controllers/controllerDispatcher.js | 1 + .../controllerModules/webSurfaceLaserInput.js | 56 +++++++++++++------ 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/scripts/system/controllers/controllerDispatcher.js b/scripts/system/controllers/controllerDispatcher.js index 4002fd297b..09d09248fc 100644 --- a/scripts/system/controllers/controllerDispatcher.js +++ b/scripts/system/controllers/controllerDispatcher.js @@ -298,6 +298,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); triggerValues: [_this.leftTriggerValue, _this.rightTriggerValue], triggerClicks: [_this.leftTriggerClicked, _this.rightTriggerClicked], secondaryValues: [_this.leftSecondaryValue, _this.rightSecondaryValue], + pointers: [_this.leftPointer, _this.rightPointer ], controllerLocations: controllerLocations, nearbyEntityProperties: nearbyEntityProperties, nearbyEntityPropertiesByID: nearbyEntityPropertiesByID, diff --git a/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js b/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js index 03c8a65637..3ee50d0f75 100644 --- a/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js +++ b/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js @@ -5,11 +5,12 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -/* global Script, Entities, Controller, RIGHT_HAND, LEFT_HAND, enableDispatcherModule, disableDispatcherModule, - makeRunningValues, Messages, Quat, Vec3, makeDispatcherModuleParameters, Overlays, ZERO_VEC, HMD, - INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, getGrabPointSphereOffset, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, - COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_ON_VALUE, - TRIGGER_OFF_VALUE, getEnabledModuleByName, PICK_MAX_DISTANCE, ContextOverlay, Picks, makeLaserParams +/* global Script, Entities, Controller, RIGHT_HAND, LEFT_HAND, getControllerWorldLocation, + enableDispatcherModule, disableDispatcherModule, makeRunningValues, Messages, Quat, Vec3, + makeDispatcherModuleParameters, Overlays, ZERO_VEC, HMD, INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, + getGrabPointSphereOffset, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, + COLORS_GRAB_DISTANCE_HOLD, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_ON_VALUE, TRIGGER_OFF_VALUE, + getEnabledModuleByName, PICK_MAX_DISTANCE, ContextOverlay, Picks, makeLaserParams */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); @@ -19,6 +20,8 @@ Script.include("/~/system/libraries/controllers.js"); function WebSurfaceLaserInput(hand) { this.hand = hand; this.otherHand = this.hand === RIGHT_HAND ? LEFT_HAND : RIGHT_HAND; + this.ignoredEntities = []; + this.lastObjectID = null; this.running = false; this.parameters = makeDispatcherModuleParameters( @@ -60,16 +63,20 @@ Script.include("/~/system/libraries/controllers.js"); return this.hand === RIGHT_HAND ? leftOverlayLaserInput : rightOverlayLaserInput; }; - this.isPointingAtGrabbableEntity = function(controllerData, triggerPressed) { + this.isPointingAtNearGrabbableEntity = function(controllerData, triggerPressed) { // we are searching for an entity that is not a web entity. We want to be able to // grab a non-web entity if the ray-pick intersects one. var intersection = controllerData.rayPicks[this.hand]; if (intersection.type === Picks.INTERSECTED_ENTITY) { // is pointing at an entity. - var entityProperty = Entities.getEntityProperties(intersection.objectID); - var entityType = entityProperty.type; - var isGrabbable = entityIsGrabbable(entityProperty); - return (isGrabbable && triggerPressed && entityType !== "Web"); + var entityProperties = Entities.getEntityProperties(intersection.objectID); + var entityType = entityProperties.type; + if (entityIsGrabbable(entityProperties)) { + // check if entity is near grabbable. + var distance = Vec3.distance(entityProperties.position, controllerData.controllerLocations[this.hand].position); + if (distance <= NEAR_GRAB_RADIUS * MyAvatar.sensorToWorldScale) + return (triggerPressed && entityType !== "Web"); + } } return false; }; @@ -78,21 +85,30 @@ Script.include("/~/system/libraries/controllers.js"); // allow pointing at tablet, unlocked web entities, or web overlays automatically without pressing trigger, // but for pointing at locked web entities or non-web overlays user must be pressing trigger var intersection = controllerData.rayPicks[this.hand]; + var objectID = intersection.objectID; if (intersection.type === Picks.INTERSECTED_OVERLAY) { - var objectID = intersection.objectID; if ((HMD.tabletID && objectID === HMD.tabletID) || (HMD.tabletScreenID && objectID === HMD.tabletScreenID) || (HMD.homeButtonID && objectID === HMD.homeButtonID)) { + this.lastObjectID = objectID; return true; } else { var overlayType = Overlays.getOverlayType(objectID); + this.lastObjectID = objectID; return overlayType === "web3d" || triggerPressed; } } else if (intersection.type === Picks.INTERSECTED_ENTITY) { - var entityProperty = Entities.getEntityProperties(intersection.objectID); - var entityType = entityProperty.type; - var isLocked = entityProperty.locked; - return entityType === "Web" && (!isLocked || triggerPressed); + var entityProperty = Entities.getEntityProperties(objectID); + if (entityProperty.type === "Web") { + var isLocked = entityProperty.locked; + this.lastObjectID = objectID; + return (!isLocked || triggerPressed); + } else if (this.ignoredEntities.indexOf(objectID) === -1 && triggerPressed && this.lastObjectID !== objectID) { + // ignore, preserve whether it's running or not. + console.log("I'm here"); + Pointers.setIgnoreItems(controllerData.pointers[this.hand], [objectID]); + this.ignoredEntities.push(objectID); + } } return false; }; @@ -110,6 +126,11 @@ Script.include("/~/system/libraries/controllers.js"); } }; + this.reAddIgnoredEntities = function(controllerData) { + Pointers.setIncludeItems(controllerData.pointers[this.hand], this.ignoredEntities); + this.ignoredEntities = []; + } + this.updateAllwaysOn = function() { var PREFER_STYLUS_OVER_LASER = "preferStylusOverLaser"; this.parameters.handLaser.allwaysOn = !Settings.getValue(PREFER_STYLUS_OVER_LASER, false); @@ -128,7 +149,7 @@ Script.include("/~/system/libraries/controllers.js"); controllerData.triggerValues[this.otherHand] <= TRIGGER_OFF_VALUE; var allowThisModule = !otherModuleRunning || isTriggerPressed; if (allowThisModule && this.isPointingAtTriggerable(controllerData, isTriggerPressed) && - !this.isPointingAtGrabbableEntity(controllerData, isTriggerPressed)) { + !this.isPointingAtNearGrabbableEntity(controllerData, isTriggerPressed)) { this.updateAllwaysOn(); if (isTriggerPressed) { this.dominantHandOverride = true; // Override dominant hand. @@ -150,11 +171,12 @@ Script.include("/~/system/libraries/controllers.js"); var isTriggerPressed = controllerData.triggerValues[this.hand] > TRIGGER_OFF_VALUE; var laserOn = isTriggerPressed || this.parameters.handLaser.allwaysOn; if (allowThisModule && (laserOn && this.isPointingAtTriggerable(controllerData, isTriggerPressed)) && - !this.isPointingAtGrabbableEntity(controllerData, isTriggerPressed)) { + !this.isPointingAtNearGrabbableEntity(controllerData, isTriggerPressed)) { this.running = true; return makeRunningValues(true, [], []); } this.deleteContextOverlay(); + this.reAddIgnoredEntities(controllerData); this.running = false; this.dominantHandOverride = false; return makeRunningValues(false, [], []); From 4e3a6cb320b8ea8507512c8d5a7ab54a52cf737f Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Fri, 20 Jul 2018 11:18:20 -0700 Subject: [PATCH 010/545] adding ignore for far-/near- grabbable entities when operating on web surface --- .../controllerModules/webSurfaceLaserInput.js | 35 ++++++------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js b/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js index 3ee50d0f75..16e2c1a4f7 100644 --- a/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js +++ b/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js @@ -20,8 +20,6 @@ Script.include("/~/system/libraries/controllers.js"); function WebSurfaceLaserInput(hand) { this.hand = hand; this.otherHand = this.hand === RIGHT_HAND ? LEFT_HAND : RIGHT_HAND; - this.ignoredEntities = []; - this.lastObjectID = null; this.running = false; this.parameters = makeDispatcherModuleParameters( @@ -71,11 +69,15 @@ Script.include("/~/system/libraries/controllers.js"); // is pointing at an entity. var entityProperties = Entities.getEntityProperties(intersection.objectID); var entityType = entityProperties.type; - if (entityIsGrabbable(entityProperties)) { + if (entityIsGrabbable(entityProperties) && entityType !== "Web") { // check if entity is near grabbable. var distance = Vec3.distance(entityProperties.position, controllerData.controllerLocations[this.hand].position); - if (distance <= NEAR_GRAB_RADIUS * MyAvatar.sensorToWorldScale) - return (triggerPressed && entityType !== "Web"); + if (distance <= NEAR_GRAB_RADIUS * MyAvatar.sensorToWorldScale) { + return triggerPressed; + } else { + // far-grabbable, but still return it as true anyway + return false; + } } } return false; @@ -90,25 +92,15 @@ Script.include("/~/system/libraries/controllers.js"); if ((HMD.tabletID && objectID === HMD.tabletID) || (HMD.tabletScreenID && objectID === HMD.tabletScreenID) || (HMD.homeButtonID && objectID === HMD.homeButtonID)) { - this.lastObjectID = objectID; return true; } else { var overlayType = Overlays.getOverlayType(objectID); - this.lastObjectID = objectID; return overlayType === "web3d" || triggerPressed; } } else if (intersection.type === Picks.INTERSECTED_ENTITY) { var entityProperty = Entities.getEntityProperties(objectID); - if (entityProperty.type === "Web") { - var isLocked = entityProperty.locked; - this.lastObjectID = objectID; - return (!isLocked || triggerPressed); - } else if (this.ignoredEntities.indexOf(objectID) === -1 && triggerPressed && this.lastObjectID !== objectID) { - // ignore, preserve whether it's running or not. - console.log("I'm here"); - Pointers.setIgnoreItems(controllerData.pointers[this.hand], [objectID]); - this.ignoredEntities.push(objectID); - } + var isLocked = entityProperty.locked; + return (!isLocked || triggerPressed || entityProperty.type === "Web"); } return false; }; @@ -126,11 +118,6 @@ Script.include("/~/system/libraries/controllers.js"); } }; - this.reAddIgnoredEntities = function(controllerData) { - Pointers.setIncludeItems(controllerData.pointers[this.hand], this.ignoredEntities); - this.ignoredEntities = []; - } - this.updateAllwaysOn = function() { var PREFER_STYLUS_OVER_LASER = "preferStylusOverLaser"; this.parameters.handLaser.allwaysOn = !Settings.getValue(PREFER_STYLUS_OVER_LASER, false); @@ -148,8 +135,7 @@ Script.include("/~/system/libraries/controllers.js"); var isTriggerPressed = controllerData.triggerValues[this.hand] > TRIGGER_OFF_VALUE && controllerData.triggerValues[this.otherHand] <= TRIGGER_OFF_VALUE; var allowThisModule = !otherModuleRunning || isTriggerPressed; - if (allowThisModule && this.isPointingAtTriggerable(controllerData, isTriggerPressed) && - !this.isPointingAtNearGrabbableEntity(controllerData, isTriggerPressed)) { + if (allowThisModule && this.isPointingAtTriggerable(controllerData, isTriggerPressed)) { this.updateAllwaysOn(); if (isTriggerPressed) { this.dominantHandOverride = true; // Override dominant hand. @@ -176,7 +162,6 @@ Script.include("/~/system/libraries/controllers.js"); return makeRunningValues(true, [], []); } this.deleteContextOverlay(); - this.reAddIgnoredEntities(controllerData); this.running = false; this.dominantHandOverride = false; return makeRunningValues(false, [], []); From be5fdef974c66ec7a4525acddb07d48870b5adba Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Fri, 20 Jul 2018 15:26:55 -0700 Subject: [PATCH 011/545] adding check in isReady for grabbing non-web entitys --- .../controllers/controllerDispatcher.js | 48 ++++++++++++++++++- .../controllerModules/webSurfaceLaserInput.js | 19 ++++---- 2 files changed, 57 insertions(+), 10 deletions(-) diff --git a/scripts/system/controllers/controllerDispatcher.js b/scripts/system/controllers/controllerDispatcher.js index 09d09248fc..8dbf4a6789 100644 --- a/scripts/system/controllers/controllerDispatcher.js +++ b/scripts/system/controllers/controllerDispatcher.js @@ -31,6 +31,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); var PROFILE = false; var DEBUG = false; + var DEBUG_OVERLAY = true; if (typeof Test !== "undefined") { PROFILE = true; @@ -48,6 +49,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); this.tabletID = null; this.blacklist = []; this.pointerManager = new PointerManager(); + this.debugOverlayID = null; // a module can occupy one or more "activity" slots while it's running. If all the required slots for a module are // not set to false (not in use), a module cannot start. When a module is using a slot, that module's name @@ -298,7 +300,6 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); triggerValues: [_this.leftTriggerValue, _this.rightTriggerValue], triggerClicks: [_this.leftTriggerClicked, _this.rightTriggerClicked], secondaryValues: [_this.leftSecondaryValue, _this.rightSecondaryValue], - pointers: [_this.leftPointer, _this.rightPointer ], controllerLocations: controllerLocations, nearbyEntityProperties: nearbyEntityProperties, nearbyEntityPropertiesByID: nearbyEntityPropertiesByID, @@ -378,6 +379,48 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); } } _this.pointerManager.updatePointersRenderState(controllerData.triggerClicks, controllerData.triggerValues); + + if (DEBUG_OVERLAY) { + if (!_this.debugOverlayID) { + + var textWidth = 0.4; + var textHeight = 0.3; + var numberOfLines = 15; + var textMargin = 0.02; + var lineHeight = (textHeight - (2 * textMargin)) / numberOfLines; + + _this.debugOverlayID = Overlays.addOverlay("text3d", { + localPosition: { x: 0.3, y: 0.2, z: 1.1 }, + localRotation: { x: 0.0, y: 0.0, z: 0.0, w: 1.0 }, + parentID: MyAvatar.sessionUUID, + parentJointIndex: MyAvatar.getJointIndex("Head"), + dimensions: { x: textWidth, y: textHeight }, + backgroundColor: { red: 0, green: 0, blue: 0 }, + color: { red: 255, green: 255, blue: 255 }, + topMargin: textMargin, + leftMargin: textMargin, + bottomMargin: textMargin, + rightMargin: textMargin, + text: "", + lineHeight: lineHeight, + alpha: 0.9, + backgroundAlpha: 0.9, + ignoreRayIntersection: true, + visible: true, + isFacingAvatar: true + }); + } + + var debugText = ""; + Object.keys(_this.runningPluginNames).forEach(function (pluginName) { + if (_this.runningPluginNames[pluginName]) { + var plugin = controllerDispatcherPlugins[pluginName]; + debugText += pluginName + ": " + plugin.parameters.priority + "\n"; + } + }); + Overlays.editOverlay(_this.debugOverlayID, { text: debugText }); + } + if (PROFILE) { Script.endProfileRange("dispatch.run"); } @@ -481,6 +524,9 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); this.cleanup = function () { Controller.disableMapping(MAPPING_NAME); _this.pointerManager.removePointers(); + if (_this.debugOverlayID) { + Overlays.deleteOverlay(_this.debugOverlayID); + } Pointers.removePointer(this.mouseRayPick); Selection.disableListHighlight(DISPATCHER_HOVERING_LIST); }; diff --git a/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js b/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js index 16e2c1a4f7..16cf2eef5c 100644 --- a/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js +++ b/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js @@ -5,12 +5,11 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -/* global Script, Entities, Controller, RIGHT_HAND, LEFT_HAND, getControllerWorldLocation, - enableDispatcherModule, disableDispatcherModule, makeRunningValues, Messages, Quat, Vec3, - makeDispatcherModuleParameters, Overlays, ZERO_VEC, HMD, INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, - getGrabPointSphereOffset, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, - COLORS_GRAB_DISTANCE_HOLD, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_ON_VALUE, TRIGGER_OFF_VALUE, - getEnabledModuleByName, PICK_MAX_DISTANCE, ContextOverlay, Picks, makeLaserParams +/* global Script, Entities, Controller, RIGHT_HAND, LEFT_HAND, enableDispatcherModule, disableDispatcherModule, + makeRunningValues, Messages, Quat, Vec3, makeDispatcherModuleParameters, Overlays, ZERO_VEC, HMD, + INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, getGrabPointSphereOffset, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, + COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_ON_VALUE, + TRIGGER_OFF_VALUE, getEnabledModuleByName, PICK_MAX_DISTANCE, ContextOverlay, Picks, makeLaserParams */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); @@ -76,7 +75,7 @@ Script.include("/~/system/libraries/controllers.js"); return triggerPressed; } else { // far-grabbable, but still return it as true anyway - return false; + return true; } } } @@ -99,8 +98,9 @@ Script.include("/~/system/libraries/controllers.js"); } } else if (intersection.type === Picks.INTERSECTED_ENTITY) { var entityProperty = Entities.getEntityProperties(objectID); + var entityType = entityProperty.type; var isLocked = entityProperty.locked; - return (!isLocked || triggerPressed || entityProperty.type === "Web"); + return (!isLocked || triggerPressed || entityType === "Web"); } return false; }; @@ -135,7 +135,8 @@ Script.include("/~/system/libraries/controllers.js"); var isTriggerPressed = controllerData.triggerValues[this.hand] > TRIGGER_OFF_VALUE && controllerData.triggerValues[this.otherHand] <= TRIGGER_OFF_VALUE; var allowThisModule = !otherModuleRunning || isTriggerPressed; - if (allowThisModule && this.isPointingAtTriggerable(controllerData, isTriggerPressed)) { + if (allowThisModule && this.isPointingAtTriggerable(controllerData, isTriggerPressed) && + !this.isPointingAtNearGrabbableEntity(controllerData, isTriggerPressed)) { this.updateAllwaysOn(); if (isTriggerPressed) { this.dominantHandOverride = true; // Override dominant hand. From e9ab2b8f27db38a81f114c89fd0d66308c76d1c9 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 20 Jul 2018 16:48:15 -0700 Subject: [PATCH 012/545] enable LOD manager on android --- interface/src/Application.cpp | 2 -- interface/src/LODManager.h | 4 ++++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 311c08b858..0da3d9445e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5803,9 +5803,7 @@ void Application::update(float deltaTime) { bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::update()"); -#if !defined(Q_OS_ANDROID) updateLOD(deltaTime); -#endif // TODO: break these out into distinct perfTimers when they prove interesting { diff --git a/interface/src/LODManager.h b/interface/src/LODManager.h index 8f88da63a8..8cae179f1e 100644 --- a/interface/src/LODManager.h +++ b/interface/src/LODManager.h @@ -19,7 +19,11 @@ #include #include +#ifdef Q_OS_ANDROID +const float DEFAULT_DESKTOP_LOD_DOWN_FPS = 10.0f; +#else const float DEFAULT_DESKTOP_LOD_DOWN_FPS = 30.0f; +#endif const float DEFAULT_HMD_LOD_DOWN_FPS = 34.0f; const float DEFAULT_DESKTOP_MAX_RENDER_TIME = (float)MSECS_PER_SECOND / DEFAULT_DESKTOP_LOD_DOWN_FPS; // msec const float DEFAULT_HMD_MAX_RENDER_TIME = (float)MSECS_PER_SECOND / DEFAULT_HMD_LOD_DOWN_FPS; // msec From 32886d67d98b7d2b964b25e39ce1a821a05593fe Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Fri, 20 Jul 2018 17:17:36 -0700 Subject: [PATCH 013/545] optimizing near-/far- grabbable entities a bit --- .../controllers/controllerDispatcher.js | 74 +++---- .../system/controllers/controllerModules/' | 181 ++++++++++++++++++ .../controllerModules/webSurfaceLaserInput.js | 12 +- 3 files changed, 223 insertions(+), 44 deletions(-) create mode 100644 scripts/system/controllers/controllerModules/' diff --git a/scripts/system/controllers/controllerDispatcher.js b/scripts/system/controllers/controllerDispatcher.js index 8dbf4a6789..399ccf0ba3 100644 --- a/scripts/system/controllers/controllerDispatcher.js +++ b/scripts/system/controllers/controllerDispatcher.js @@ -380,46 +380,46 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); } _this.pointerManager.updatePointersRenderState(controllerData.triggerClicks, controllerData.triggerValues); - if (DEBUG_OVERLAY) { - if (!_this.debugOverlayID) { +/* if (DEBUG_OVERLAY) {*/ + //if (!_this.debugOverlayID) { - var textWidth = 0.4; - var textHeight = 0.3; - var numberOfLines = 15; - var textMargin = 0.02; - var lineHeight = (textHeight - (2 * textMargin)) / numberOfLines; + //var textWidth = 0.4; + //var textHeight = 0.3; + //var numberOfLines = 15; + //var textMargin = 0.02; + //var lineHeight = (textHeight - (2 * textMargin)) / numberOfLines; - _this.debugOverlayID = Overlays.addOverlay("text3d", { - localPosition: { x: 0.3, y: 0.2, z: 1.1 }, - localRotation: { x: 0.0, y: 0.0, z: 0.0, w: 1.0 }, - parentID: MyAvatar.sessionUUID, - parentJointIndex: MyAvatar.getJointIndex("Head"), - dimensions: { x: textWidth, y: textHeight }, - backgroundColor: { red: 0, green: 0, blue: 0 }, - color: { red: 255, green: 255, blue: 255 }, - topMargin: textMargin, - leftMargin: textMargin, - bottomMargin: textMargin, - rightMargin: textMargin, - text: "", - lineHeight: lineHeight, - alpha: 0.9, - backgroundAlpha: 0.9, - ignoreRayIntersection: true, - visible: true, - isFacingAvatar: true - }); - } + //_this.debugOverlayID = Overlays.addOverlay("text3d", { + //localPosition: { x: 0.3, y: 0.2, z: 1.1 }, + //localRotation: { x: 0.0, y: 0.0, z: 0.0, w: 1.0 }, + //parentID: MyAvatar.sessionUUID, + //parentJointIndex: MyAvatar.getJointIndex("Head"), + //dimensions: { x: textWidth, y: textHeight }, + //backgroundColor: { red: 0, green: 0, blue: 0 }, + //color: { red: 255, green: 255, blue: 255 }, + //topMargin: textMargin, + //leftMargin: textMargin, + //bottomMargin: textMargin, + //rightMargin: textMargin, + //text: "", + //lineHeight: lineHeight, + //alpha: 0.9, + //backgroundAlpha: 0.9, + //ignoreRayIntersection: true, + //visible: true, + //isFacingAvatar: true + //}); + //} - var debugText = ""; - Object.keys(_this.runningPluginNames).forEach(function (pluginName) { - if (_this.runningPluginNames[pluginName]) { - var plugin = controllerDispatcherPlugins[pluginName]; - debugText += pluginName + ": " + plugin.parameters.priority + "\n"; - } - }); - Overlays.editOverlay(_this.debugOverlayID, { text: debugText }); - } + //var debugText = ""; + //Object.keys(_this.runningPluginNames).forEach(function (pluginName) { + //if (_this.runningPluginNames[pluginName]) { + //var plugin = controllerDispatcherPlugins[pluginName]; + //debugText += pluginName + ": " + plugin.parameters.priority + "\n"; + //} + //}); + //Overlays.editOverlay(_this.debugOverlayID, { text: debugText }); + /*}*/ if (PROFILE) { Script.endProfileRange("dispatch.run"); diff --git a/scripts/system/controllers/controllerModules/' b/scripts/system/controllers/controllerModules/' new file mode 100644 index 0000000000..8217e0d022 --- /dev/null +++ b/scripts/system/controllers/controllerModules/' @@ -0,0 +1,181 @@ +"use strict"; + +// webSurfaceLaserInput.js +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html + +/* global Script, Entities, Controller, RIGHT_HAND, LEFT_HAND, enableDispatcherModule, disableDispatcherModule, + makeRunningValues, Messages, Quat, Vec3, makeDispatcherModuleParameters, Overlays, ZERO_VEC, HMD, + INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, getGrabPointSphereOffset, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, + COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_ON_VALUE, + TRIGGER_OFF_VALUE, getEnabledModuleByName, PICK_MAX_DISTANCE, ContextOverlay, Picks, makeLaserParams +*/ + +Script.include("/~/system/libraries/controllerDispatcherUtils.js"); +Script.include("/~/system/libraries/controllers.js"); + +(function() { + function WebSurfaceLaserInput(hand) { + this.hand = hand; + this.otherHand = this.hand === RIGHT_HAND ? LEFT_HAND : RIGHT_HAND; + this.running = false; + + this.parameters = makeDispatcherModuleParameters( + 160, + this.hand === RIGHT_HAND ? ["rightHand"] : ["leftHand"], + [], + 100, + makeLaserParams(hand, true)); + + this.grabModuleWantsNearbyOverlay = function(controllerData) { + if (controllerData.triggerValues[this.hand] > TRIGGER_ON_VALUE) { + var nearGrabName = this.hand === RIGHT_HAND ? "RightNearParentingGrabOverlay" : "LeftNearParentingGrabOverlay"; + var nearGrabModule = getEnabledModuleByName(nearGrabName); + if (nearGrabModule) { + var candidateOverlays = controllerData.nearbyOverlayIDs[this.hand]; + var grabbableOverlays = candidateOverlays.filter(function(overlayID) { + return Overlays.getProperty(overlayID, "grabbable"); + }); + var target = nearGrabModule.getTargetID(grabbableOverlays, controllerData); + if (target) { + return true; + } + } + nearGrabName = this.hand === RIGHT_HAND ? "RightNearParentingGrabEntity" : "LeftNearParentingGrabEntity"; + nearGrabModule = getEnabledModuleByName(nearGrabName); + if (nearGrabModule && nearGrabModule.isReady(controllerData)) { + return nearGrabModule.isReady(controllerData).active; + } + nearGrabName = this.hand === RIGHT_HAND ? "RightNearActionGrabEntity" : "LeftNearActionGrabEntity"; + nearGrabModule = getEnabledModuleByName(nearGrabName); + if (nearGrabModule && nearGrabModule.isReady(controllerData)) { + return nearGrabModule.isReady(controllerData).active; + } + } + return false; + }; + + this.getOtherModule = function() { + return this.hand === RIGHT_HAND ? leftOverlayLaserInput : rightOverlayLaserInput; + }; + + this.isPointingAtNearGrabbableEntity = function(controllerData, triggerPressed) { + // we are searching for an entity that is not a web entity. We want to be able to + // grab a non-web entity if the ray-pick intersects one. + var intersection = controllerData.rayPicks[this.hand]; + if (intersection.type === Picks.INTERSECTED_ENTITY) { + // is pointing at an entity. + var entityProperties = Entities.getEntityProperties(intersection.objectID); + var entityType = entityProperties.type; + if (entityIsGrabbable(entityProperties) && entityType !== "Web") { + // check if entity is near grabbable. + var distance = Vec3.distance(entityProperties.position, controllerData.controllerLocations[this.hand].position); + if (distance >= NEAR_GRAB_RADIUS * MyAvatar.sensorToWorldScale) { + // far-grabbable, but still return it as true anyway + return true; + } + } + } + return false; + }; + + this.isPointingAtTriggerable = function(controllerData, triggerPressed) { + // allow pointing at tablet, unlocked web entities, or web overlays automatically without pressing trigger, + // but for pointing at locked web entities or non-web overlays user must be pressing trigger + var intersection = controllerData.rayPicks[this.hand]; + var objectID = intersection.objectID; + if (intersection.type === Picks.INTERSECTED_OVERLAY) { + if ((HMD.tabletID && objectID === HMD.tabletID) || + (HMD.tabletScreenID && objectID === HMD.tabletScreenID) || + (HMD.homeButtonID && objectID === HMD.homeButtonID)) { + return true; + } else { + var overlayType = Overlays.getOverlayType(objectID); + return overlayType === "web3d" || triggerPressed; + } + } else if (intersection.type === Picks.INTERSECTED_ENTITY) { + var entityProperty = Entities.getEntityProperties(objectID); + var entityType = entityProperty.type; + var isLocked = entityProperty.locked; + return (!isLocked || triggerPressed || entityType === "Web"); + } + return false; + }; + + this.deleteContextOverlay = function() { + var farGrabModule = getEnabledModuleByName(this.hand === RIGHT_HAND + ? "RightFarActionGrabEntity" : "LeftFarActionGrabEntity"); + if (farGrabModule) { + var entityWithContextOverlay = farGrabModule.entityWithContextOverlay; + + if (entityWithContextOverlay) { + ContextOverlay.destroyContextOverlay(entityWithContextOverlay); + farGrabModule.entityWithContextOverlay = false; + } + } + }; + + this.updateAllwaysOn = function() { + var PREFER_STYLUS_OVER_LASER = "preferStylusOverLaser"; + this.parameters.handLaser.allwaysOn = !Settings.getValue(PREFER_STYLUS_OVER_LASER, false); + }; + + this.getDominantHand = function() { + return MyAvatar.getDominantHand() === "right" ? 1 : 0; + }; + + this.dominantHandOverride = false; + + this.isReady = function(controllerData) { + var otherModuleRunning = this.getOtherModule().running; + otherModuleRunning = otherModuleRunning && this.getDominantHand() !== this.hand; // Auto-swap to dominant hand. + var isTriggerPressed = controllerData.triggerValues[this.hand] > TRIGGER_OFF_VALUE && + controllerData.triggerValues[this.otherHand] <= TRIGGER_OFF_VALUE; + var allowThisModule = !otherModuleRunning || isTriggerPressed; + if (allowThisModule && this.isPointingAtTriggerable(controllerData, isTriggerPressed) && + (controllerData.nearbyEntityProperties[this.hand] !== [])) { + this.updateAllwaysOn(); + if (isTriggerPressed) { + this.dominantHandOverride = true; // Override dominant hand. + this.getOtherModule().dominantHandOverride = false; + } + if (this.parameters.handLaser.allwaysOn || isTriggerPressed) { + return makeRunningValues(true, [], []); + } + } + return makeRunningValues(false, [], []); + }; + + this.run = function(controllerData, deltaTime) { + var otherModuleRunning = this.getOtherModule().running; + otherModuleRunning = otherModuleRunning && this.getDominantHand() !== this.hand; // Auto-swap to dominant hand. + otherModuleRunning = otherModuleRunning || this.getOtherModule().dominantHandOverride; // Override dominant hand. + var grabModuleNeedsToRun = this.grabModuleWantsNearbyOverlay(controllerData); + var allowThisModule = !otherModuleRunning && !grabModuleNeedsToRun; + var isTriggerPressed = controllerData.triggerValues[this.hand] > TRIGGER_OFF_VALUE; + var laserOn = isTriggerPressed || this.parameters.handLaser.allwaysOn; + if (allowThisModule && (laserOn && this.isPointingAtTriggerable(controllerData, isTriggerPressed)) && + (controllerData.nearbyEntityProperties[this.hand] !== [] || (this.isPointingAtNearGrabbableEntity(controllerData, isTriggerPressed)))) { + this.running = true; + return makeRunningValues(true, [], []); + } + this.deleteContextOverlay(); + this.running = false; + this.dominantHandOverride = false; + return makeRunningValues(false, [], []); + }; + } + + var leftOverlayLaserInput = new WebSurfaceLaserInput(LEFT_HAND); + var rightOverlayLaserInput = new WebSurfaceLaserInput(RIGHT_HAND); + + enableDispatcherModule("LeftWebSurfaceLaserInput", leftOverlayLaserInput); + enableDispatcherModule("RightWebSurfaceLaserInput", rightOverlayLaserInput); + + function cleanup() { + disableDispatcherModule("LeftWebSurfaceLaserInput"); + disableDispatcherModule("RightWebSurfaceLaserInput"); + } + Script.scriptEnding.connect(cleanup); +}()); diff --git a/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js b/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js index 16cf2eef5c..dd7bccf667 100644 --- a/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js +++ b/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js @@ -60,7 +60,7 @@ Script.include("/~/system/libraries/controllers.js"); return this.hand === RIGHT_HAND ? leftOverlayLaserInput : rightOverlayLaserInput; }; - this.isPointingAtNearGrabbableEntity = function(controllerData, triggerPressed) { + this.isPointingAtFarGrabbableEntity = function(controllerData, triggerPressed) { // we are searching for an entity that is not a web entity. We want to be able to // grab a non-web entity if the ray-pick intersects one. var intersection = controllerData.rayPicks[this.hand]; @@ -71,9 +71,7 @@ Script.include("/~/system/libraries/controllers.js"); if (entityIsGrabbable(entityProperties) && entityType !== "Web") { // check if entity is near grabbable. var distance = Vec3.distance(entityProperties.position, controllerData.controllerLocations[this.hand].position); - if (distance <= NEAR_GRAB_RADIUS * MyAvatar.sensorToWorldScale) { - return triggerPressed; - } else { + if (distance >= NEAR_GRAB_RADIUS * MyAvatar.sensorToWorldScale) { // far-grabbable, but still return it as true anyway return true; } @@ -135,8 +133,8 @@ Script.include("/~/system/libraries/controllers.js"); var isTriggerPressed = controllerData.triggerValues[this.hand] > TRIGGER_OFF_VALUE && controllerData.triggerValues[this.otherHand] <= TRIGGER_OFF_VALUE; var allowThisModule = !otherModuleRunning || isTriggerPressed; - if (allowThisModule && this.isPointingAtTriggerable(controllerData, isTriggerPressed) && - !this.isPointingAtNearGrabbableEntity(controllerData, isTriggerPressed)) { + if (allowThisModule && this.isPointingAtTriggerable(controllerData, isTriggerPressed) && + (controllerData.nearbyEntityProperties[this.hand] !== [])) { this.updateAllwaysOn(); if (isTriggerPressed) { this.dominantHandOverride = true; // Override dominant hand. @@ -158,7 +156,7 @@ Script.include("/~/system/libraries/controllers.js"); var isTriggerPressed = controllerData.triggerValues[this.hand] > TRIGGER_OFF_VALUE; var laserOn = isTriggerPressed || this.parameters.handLaser.allwaysOn; if (allowThisModule && (laserOn && this.isPointingAtTriggerable(controllerData, isTriggerPressed)) && - !this.isPointingAtNearGrabbableEntity(controllerData, isTriggerPressed)) { + (controllerData.nearbyEntityProperties[this.hand] !== [] || !(this.isPointingAtFarGrabbableEntity(controllerData, isTriggerPressed)))) { this.running = true; return makeRunningValues(true, [], []); } From 1880c49d0358b535156d00671499f14fddab2979 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Fri, 20 Jul 2018 17:18:58 -0700 Subject: [PATCH 014/545] removing garbage file --- .../system/controllers/controllerModules/' | 181 ------------------ 1 file changed, 181 deletions(-) delete mode 100644 scripts/system/controllers/controllerModules/' diff --git a/scripts/system/controllers/controllerModules/' b/scripts/system/controllers/controllerModules/' deleted file mode 100644 index 8217e0d022..0000000000 --- a/scripts/system/controllers/controllerModules/' +++ /dev/null @@ -1,181 +0,0 @@ -"use strict"; - -// webSurfaceLaserInput.js -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html - -/* global Script, Entities, Controller, RIGHT_HAND, LEFT_HAND, enableDispatcherModule, disableDispatcherModule, - makeRunningValues, Messages, Quat, Vec3, makeDispatcherModuleParameters, Overlays, ZERO_VEC, HMD, - INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, getGrabPointSphereOffset, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, - COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_ON_VALUE, - TRIGGER_OFF_VALUE, getEnabledModuleByName, PICK_MAX_DISTANCE, ContextOverlay, Picks, makeLaserParams -*/ - -Script.include("/~/system/libraries/controllerDispatcherUtils.js"); -Script.include("/~/system/libraries/controllers.js"); - -(function() { - function WebSurfaceLaserInput(hand) { - this.hand = hand; - this.otherHand = this.hand === RIGHT_HAND ? LEFT_HAND : RIGHT_HAND; - this.running = false; - - this.parameters = makeDispatcherModuleParameters( - 160, - this.hand === RIGHT_HAND ? ["rightHand"] : ["leftHand"], - [], - 100, - makeLaserParams(hand, true)); - - this.grabModuleWantsNearbyOverlay = function(controllerData) { - if (controllerData.triggerValues[this.hand] > TRIGGER_ON_VALUE) { - var nearGrabName = this.hand === RIGHT_HAND ? "RightNearParentingGrabOverlay" : "LeftNearParentingGrabOverlay"; - var nearGrabModule = getEnabledModuleByName(nearGrabName); - if (nearGrabModule) { - var candidateOverlays = controllerData.nearbyOverlayIDs[this.hand]; - var grabbableOverlays = candidateOverlays.filter(function(overlayID) { - return Overlays.getProperty(overlayID, "grabbable"); - }); - var target = nearGrabModule.getTargetID(grabbableOverlays, controllerData); - if (target) { - return true; - } - } - nearGrabName = this.hand === RIGHT_HAND ? "RightNearParentingGrabEntity" : "LeftNearParentingGrabEntity"; - nearGrabModule = getEnabledModuleByName(nearGrabName); - if (nearGrabModule && nearGrabModule.isReady(controllerData)) { - return nearGrabModule.isReady(controllerData).active; - } - nearGrabName = this.hand === RIGHT_HAND ? "RightNearActionGrabEntity" : "LeftNearActionGrabEntity"; - nearGrabModule = getEnabledModuleByName(nearGrabName); - if (nearGrabModule && nearGrabModule.isReady(controllerData)) { - return nearGrabModule.isReady(controllerData).active; - } - } - return false; - }; - - this.getOtherModule = function() { - return this.hand === RIGHT_HAND ? leftOverlayLaserInput : rightOverlayLaserInput; - }; - - this.isPointingAtNearGrabbableEntity = function(controllerData, triggerPressed) { - // we are searching for an entity that is not a web entity. We want to be able to - // grab a non-web entity if the ray-pick intersects one. - var intersection = controllerData.rayPicks[this.hand]; - if (intersection.type === Picks.INTERSECTED_ENTITY) { - // is pointing at an entity. - var entityProperties = Entities.getEntityProperties(intersection.objectID); - var entityType = entityProperties.type; - if (entityIsGrabbable(entityProperties) && entityType !== "Web") { - // check if entity is near grabbable. - var distance = Vec3.distance(entityProperties.position, controllerData.controllerLocations[this.hand].position); - if (distance >= NEAR_GRAB_RADIUS * MyAvatar.sensorToWorldScale) { - // far-grabbable, but still return it as true anyway - return true; - } - } - } - return false; - }; - - this.isPointingAtTriggerable = function(controllerData, triggerPressed) { - // allow pointing at tablet, unlocked web entities, or web overlays automatically without pressing trigger, - // but for pointing at locked web entities or non-web overlays user must be pressing trigger - var intersection = controllerData.rayPicks[this.hand]; - var objectID = intersection.objectID; - if (intersection.type === Picks.INTERSECTED_OVERLAY) { - if ((HMD.tabletID && objectID === HMD.tabletID) || - (HMD.tabletScreenID && objectID === HMD.tabletScreenID) || - (HMD.homeButtonID && objectID === HMD.homeButtonID)) { - return true; - } else { - var overlayType = Overlays.getOverlayType(objectID); - return overlayType === "web3d" || triggerPressed; - } - } else if (intersection.type === Picks.INTERSECTED_ENTITY) { - var entityProperty = Entities.getEntityProperties(objectID); - var entityType = entityProperty.type; - var isLocked = entityProperty.locked; - return (!isLocked || triggerPressed || entityType === "Web"); - } - return false; - }; - - this.deleteContextOverlay = function() { - var farGrabModule = getEnabledModuleByName(this.hand === RIGHT_HAND - ? "RightFarActionGrabEntity" : "LeftFarActionGrabEntity"); - if (farGrabModule) { - var entityWithContextOverlay = farGrabModule.entityWithContextOverlay; - - if (entityWithContextOverlay) { - ContextOverlay.destroyContextOverlay(entityWithContextOverlay); - farGrabModule.entityWithContextOverlay = false; - } - } - }; - - this.updateAllwaysOn = function() { - var PREFER_STYLUS_OVER_LASER = "preferStylusOverLaser"; - this.parameters.handLaser.allwaysOn = !Settings.getValue(PREFER_STYLUS_OVER_LASER, false); - }; - - this.getDominantHand = function() { - return MyAvatar.getDominantHand() === "right" ? 1 : 0; - }; - - this.dominantHandOverride = false; - - this.isReady = function(controllerData) { - var otherModuleRunning = this.getOtherModule().running; - otherModuleRunning = otherModuleRunning && this.getDominantHand() !== this.hand; // Auto-swap to dominant hand. - var isTriggerPressed = controllerData.triggerValues[this.hand] > TRIGGER_OFF_VALUE && - controllerData.triggerValues[this.otherHand] <= TRIGGER_OFF_VALUE; - var allowThisModule = !otherModuleRunning || isTriggerPressed; - if (allowThisModule && this.isPointingAtTriggerable(controllerData, isTriggerPressed) && - (controllerData.nearbyEntityProperties[this.hand] !== [])) { - this.updateAllwaysOn(); - if (isTriggerPressed) { - this.dominantHandOverride = true; // Override dominant hand. - this.getOtherModule().dominantHandOverride = false; - } - if (this.parameters.handLaser.allwaysOn || isTriggerPressed) { - return makeRunningValues(true, [], []); - } - } - return makeRunningValues(false, [], []); - }; - - this.run = function(controllerData, deltaTime) { - var otherModuleRunning = this.getOtherModule().running; - otherModuleRunning = otherModuleRunning && this.getDominantHand() !== this.hand; // Auto-swap to dominant hand. - otherModuleRunning = otherModuleRunning || this.getOtherModule().dominantHandOverride; // Override dominant hand. - var grabModuleNeedsToRun = this.grabModuleWantsNearbyOverlay(controllerData); - var allowThisModule = !otherModuleRunning && !grabModuleNeedsToRun; - var isTriggerPressed = controllerData.triggerValues[this.hand] > TRIGGER_OFF_VALUE; - var laserOn = isTriggerPressed || this.parameters.handLaser.allwaysOn; - if (allowThisModule && (laserOn && this.isPointingAtTriggerable(controllerData, isTriggerPressed)) && - (controllerData.nearbyEntityProperties[this.hand] !== [] || (this.isPointingAtNearGrabbableEntity(controllerData, isTriggerPressed)))) { - this.running = true; - return makeRunningValues(true, [], []); - } - this.deleteContextOverlay(); - this.running = false; - this.dominantHandOverride = false; - return makeRunningValues(false, [], []); - }; - } - - var leftOverlayLaserInput = new WebSurfaceLaserInput(LEFT_HAND); - var rightOverlayLaserInput = new WebSurfaceLaserInput(RIGHT_HAND); - - enableDispatcherModule("LeftWebSurfaceLaserInput", leftOverlayLaserInput); - enableDispatcherModule("RightWebSurfaceLaserInput", rightOverlayLaserInput); - - function cleanup() { - disableDispatcherModule("LeftWebSurfaceLaserInput"); - disableDispatcherModule("RightWebSurfaceLaserInput"); - } - Script.scriptEnding.connect(cleanup); -}()); From a2aeacab649d77acc8399291f719ea7b0f16c758 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Mon, 23 Jul 2018 12:17:19 -0700 Subject: [PATCH 015/545] adding fix for near grabbing with web entity --- .../controllerModules/webSurfaceLaserInput.js | 25 ++++++------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js b/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js index dd7bccf667..5009bec0f5 100644 --- a/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js +++ b/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js @@ -60,25 +60,14 @@ Script.include("/~/system/libraries/controllers.js"); return this.hand === RIGHT_HAND ? leftOverlayLaserInput : rightOverlayLaserInput; }; - this.isPointingAtFarGrabbableEntity = function(controllerData, triggerPressed) { - // we are searching for an entity that is not a web entity. We want to be able to - // grab a non-web entity if the ray-pick intersects one. + this.isPointingAtNearGrabbableEntity = function(controllerData, triggerPressed) { var intersection = controllerData.rayPicks[this.hand]; - if (intersection.type === Picks.INTERSECTED_ENTITY) { - // is pointing at an entity. - var entityProperties = Entities.getEntityProperties(intersection.objectID); - var entityType = entityProperties.type; - if (entityIsGrabbable(entityProperties) && entityType !== "Web") { - // check if entity is near grabbable. - var distance = Vec3.distance(entityProperties.position, controllerData.controllerLocations[this.hand].position); - if (distance >= NEAR_GRAB_RADIUS * MyAvatar.sensorToWorldScale) { - // far-grabbable, but still return it as true anyway - return true; - } - } + var objectID = intersection.objectID; + if(intersection.type === Picks.INTERSECTED_ENTITY) { + return (controllerData.nearbyEntityPropertiesByID[objectID] !== null && triggerPressed); } return false; - }; + } this.isPointingAtTriggerable = function(controllerData, triggerPressed) { // allow pointing at tablet, unlocked web entities, or web overlays automatically without pressing trigger, @@ -98,7 +87,7 @@ Script.include("/~/system/libraries/controllers.js"); var entityProperty = Entities.getEntityProperties(objectID); var entityType = entityProperty.type; var isLocked = entityProperty.locked; - return (!isLocked || triggerPressed || entityType === "Web"); + return entityType === "Web" && (!isLocked || triggerPressed); } return false; }; @@ -156,7 +145,7 @@ Script.include("/~/system/libraries/controllers.js"); var isTriggerPressed = controllerData.triggerValues[this.hand] > TRIGGER_OFF_VALUE; var laserOn = isTriggerPressed || this.parameters.handLaser.allwaysOn; if (allowThisModule && (laserOn && this.isPointingAtTriggerable(controllerData, isTriggerPressed)) && - (controllerData.nearbyEntityProperties[this.hand] !== [] || !(this.isPointingAtFarGrabbableEntity(controllerData, isTriggerPressed)))) { + (controllerData.nearbyEntityProperties[this.hand] !== [])) { this.running = true; return makeRunningValues(true, [], []); } From 1ec136a19c04a3f9e39ee7f691667a3713eb1231 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Mon, 23 Jul 2018 12:18:26 -0700 Subject: [PATCH 016/545] removing debug overlay statements --- .../controllers/controllerDispatcher.js | 45 ------------------- 1 file changed, 45 deletions(-) diff --git a/scripts/system/controllers/controllerDispatcher.js b/scripts/system/controllers/controllerDispatcher.js index 399ccf0ba3..91ab824a54 100644 --- a/scripts/system/controllers/controllerDispatcher.js +++ b/scripts/system/controllers/controllerDispatcher.js @@ -31,7 +31,6 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); var PROFILE = false; var DEBUG = false; - var DEBUG_OVERLAY = true; if (typeof Test !== "undefined") { PROFILE = true; @@ -380,47 +379,6 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); } _this.pointerManager.updatePointersRenderState(controllerData.triggerClicks, controllerData.triggerValues); -/* if (DEBUG_OVERLAY) {*/ - //if (!_this.debugOverlayID) { - - //var textWidth = 0.4; - //var textHeight = 0.3; - //var numberOfLines = 15; - //var textMargin = 0.02; - //var lineHeight = (textHeight - (2 * textMargin)) / numberOfLines; - - //_this.debugOverlayID = Overlays.addOverlay("text3d", { - //localPosition: { x: 0.3, y: 0.2, z: 1.1 }, - //localRotation: { x: 0.0, y: 0.0, z: 0.0, w: 1.0 }, - //parentID: MyAvatar.sessionUUID, - //parentJointIndex: MyAvatar.getJointIndex("Head"), - //dimensions: { x: textWidth, y: textHeight }, - //backgroundColor: { red: 0, green: 0, blue: 0 }, - //color: { red: 255, green: 255, blue: 255 }, - //topMargin: textMargin, - //leftMargin: textMargin, - //bottomMargin: textMargin, - //rightMargin: textMargin, - //text: "", - //lineHeight: lineHeight, - //alpha: 0.9, - //backgroundAlpha: 0.9, - //ignoreRayIntersection: true, - //visible: true, - //isFacingAvatar: true - //}); - //} - - //var debugText = ""; - //Object.keys(_this.runningPluginNames).forEach(function (pluginName) { - //if (_this.runningPluginNames[pluginName]) { - //var plugin = controllerDispatcherPlugins[pluginName]; - //debugText += pluginName + ": " + plugin.parameters.priority + "\n"; - //} - //}); - //Overlays.editOverlay(_this.debugOverlayID, { text: debugText }); - /*}*/ - if (PROFILE) { Script.endProfileRange("dispatch.run"); } @@ -524,9 +482,6 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); this.cleanup = function () { Controller.disableMapping(MAPPING_NAME); _this.pointerManager.removePointers(); - if (_this.debugOverlayID) { - Overlays.deleteOverlay(_this.debugOverlayID); - } Pointers.removePointer(this.mouseRayPick); Selection.disableListHighlight(DISPATCHER_HOVERING_LIST); }; From e4a5be668a15aa603e3210b2053c2bc62ad2536a Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Mon, 23 Jul 2018 12:29:01 -0700 Subject: [PATCH 017/545] adding check function for pointing at near grabbable entity --- scripts/system/controllers/controllerDispatcher.js | 2 -- .../controllers/controllerModules/webSurfaceLaserInput.js | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/scripts/system/controllers/controllerDispatcher.js b/scripts/system/controllers/controllerDispatcher.js index 91ab824a54..4002fd297b 100644 --- a/scripts/system/controllers/controllerDispatcher.js +++ b/scripts/system/controllers/controllerDispatcher.js @@ -48,7 +48,6 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); this.tabletID = null; this.blacklist = []; this.pointerManager = new PointerManager(); - this.debugOverlayID = null; // a module can occupy one or more "activity" slots while it's running. If all the required slots for a module are // not set to false (not in use), a module cannot start. When a module is using a slot, that module's name @@ -378,7 +377,6 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); } } _this.pointerManager.updatePointersRenderState(controllerData.triggerClicks, controllerData.triggerValues); - if (PROFILE) { Script.endProfileRange("dispatch.run"); } diff --git a/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js b/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js index 5009bec0f5..92423f0670 100644 --- a/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js +++ b/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js @@ -123,7 +123,7 @@ Script.include("/~/system/libraries/controllers.js"); controllerData.triggerValues[this.otherHand] <= TRIGGER_OFF_VALUE; var allowThisModule = !otherModuleRunning || isTriggerPressed; if (allowThisModule && this.isPointingAtTriggerable(controllerData, isTriggerPressed) && - (controllerData.nearbyEntityProperties[this.hand] !== [])) { + !this.isPointingAtNearGrabbableEntity(controllerData, isTriggerPressed)) { this.updateAllwaysOn(); if (isTriggerPressed) { this.dominantHandOverride = true; // Override dominant hand. @@ -145,7 +145,7 @@ Script.include("/~/system/libraries/controllers.js"); var isTriggerPressed = controllerData.triggerValues[this.hand] > TRIGGER_OFF_VALUE; var laserOn = isTriggerPressed || this.parameters.handLaser.allwaysOn; if (allowThisModule && (laserOn && this.isPointingAtTriggerable(controllerData, isTriggerPressed)) && - (controllerData.nearbyEntityProperties[this.hand] !== [])) { + !this.isPointingAtNearGrabbableEntity(controllerData, isTriggerPressed)) { this.running = true; return makeRunningValues(true, [], []); } From c0dfbac480ab9cbed8f7d2e90197a903439639ce Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Tue, 24 Jul 2018 10:04:51 -0700 Subject: [PATCH 018/545] adding comment for possible solution - still WIP --- .../controllers/controllerModules/webSurfaceLaserInput.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js b/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js index 92423f0670..ef9ff0c6ae 100644 --- a/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js +++ b/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js @@ -124,6 +124,7 @@ Script.include("/~/system/libraries/controllers.js"); var allowThisModule = !otherModuleRunning || isTriggerPressed; if (allowThisModule && this.isPointingAtTriggerable(controllerData, isTriggerPressed) && !this.isPointingAtNearGrabbableEntity(controllerData, isTriggerPressed)) { + //(controllerData.nearbyEntityProperties[this.hand] !== [])) { this.updateAllwaysOn(); if (isTriggerPressed) { this.dominantHandOverride = true; // Override dominant hand. @@ -146,6 +147,7 @@ Script.include("/~/system/libraries/controllers.js"); var laserOn = isTriggerPressed || this.parameters.handLaser.allwaysOn; if (allowThisModule && (laserOn && this.isPointingAtTriggerable(controllerData, isTriggerPressed)) && !this.isPointingAtNearGrabbableEntity(controllerData, isTriggerPressed)) { + //(controllerData.nearbyEntityProperties[this.hand] !== [])) { this.running = true; return makeRunningValues(true, [], []); } From 78001a4e31d1e53b36d31b3a342b965ee839ee8c Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Mon, 30 Jul 2018 18:44:39 -0700 Subject: [PATCH 019/545] adding fix --- scripts/developer/utilities/audio/Stats.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/developer/utilities/audio/Stats.qml b/scripts/developer/utilities/audio/Stats.qml index 7f559ea664..e2cf028779 100644 --- a/scripts/developer/utilities/audio/Stats.qml +++ b/scripts/developer/utilities/audio/Stats.qml @@ -12,7 +12,7 @@ import QtQuick 2.5 import QtQuick.Controls 1.4 import QtQuick.Layouts 1.3 -import "../../../../resources/qml/controls-uit" as HifiControls +import "qrc:////qml//controls-uit" as HifiControls Column { id: stats @@ -25,7 +25,7 @@ Column { HifiControls.Button { id: toggleGraphs - property bool checked: false + checked: false anchors.horizontalCenter: parent.horizontalCenter text: checked ? "Hide graphs" : "Show graphs" onClicked: function() { checked = !checked; } From b020e17ee70fd700638801300f2cc4eed2704fa2 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Tue, 31 Jul 2018 10:46:19 -0700 Subject: [PATCH 020/545] rectifying toggle graph behavior --- scripts/developer/utilities/audio/Stats.qml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/developer/utilities/audio/Stats.qml b/scripts/developer/utilities/audio/Stats.qml index e2cf028779..57963732c8 100644 --- a/scripts/developer/utilities/audio/Stats.qml +++ b/scripts/developer/utilities/audio/Stats.qml @@ -17,7 +17,7 @@ import "qrc:////qml//controls-uit" as HifiControls Column { id: stats width: parent.width - property bool showGraphs: toggleGraphs.checked + property alias showGraphs: toggleGraphs.toggle Item { width: parent.width @@ -25,10 +25,10 @@ Column { HifiControls.Button { id: toggleGraphs - checked: false + property bool toggle: false anchors.horizontalCenter: parent.horizontalCenter - text: checked ? "Hide graphs" : "Show graphs" - onClicked: function() { checked = !checked; } + text: toggle ? "Hide graphs" : "Show graphs" + onClicked: { toggle = !toggle;} } } From f19a553e270b4c76afd245168aff7bd0e8a0b573 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Tue, 31 Jul 2018 10:49:30 -0700 Subject: [PATCH 021/545] adding fix for HMD mode --- scripts/developer/utilities/audio/TabletStats.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/developer/utilities/audio/TabletStats.qml b/scripts/developer/utilities/audio/TabletStats.qml index 130b90f032..2f8d212a2a 100644 --- a/scripts/developer/utilities/audio/TabletStats.qml +++ b/scripts/developer/utilities/audio/TabletStats.qml @@ -12,7 +12,7 @@ import QtQuick 2.5 import QtQuick.Controls 1.4 import QtQuick.Layouts 1.3 -import "../../../../resources/qml/styles-uit" +import "qrc:////qml//styles-uit" Item { id: dialog From 0b7d6cb7203a60e7f4b31154b4de8db01c498028 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Tue, 31 Jul 2018 14:10:19 -0700 Subject: [PATCH 022/545] start interstitial page work --- interface/src/Application.cpp | 12 ++++++++++++ interface/src/Application.h | 3 +++ libraries/audio-client/src/AudioClient.cpp | 8 ++++---- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 136e44855a..b638c51342 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3412,6 +3412,16 @@ bool Application::isServerlessMode() const { return false; } +bool Application::isInterstitialPage() { + return _interstitialMode; +} + +void Application::setInterstitialMode(bool interstitialMode) { + if (_interstitialMode != interstitialMode) { + _interstitialMode = interstitialMode; + } +} + void Application::setIsServerlessMode(bool serverlessDomain) { auto tree = getEntities()->getTree(); if (tree) { @@ -5471,6 +5481,8 @@ static bool domainLoadingInProgress = false; void Application::update(float deltaTime) { PROFILE_RANGE_EX(app, __FUNCTION__, 0xffff0000, (uint64_t)_renderFrameCount + 1); + auto audioClient = DependencyManager::get(); + audioClient->setMuted(true); if (!_physicsEnabled) { if (!domainLoadingInProgress) { PROFILE_ASYNC_BEGIN(app, "Scene Loading", ""); diff --git a/interface/src/Application.h b/interface/src/Application.h index 94e561e550..c084c0033f 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -304,6 +304,7 @@ public: void saveNextPhysicsStats(QString filename); bool isServerlessMode() const; + bool isInterstitialMode() const; void replaceDomainContent(const QString& url); @@ -423,6 +424,7 @@ public slots: void setPreferredCursor(const QString& cursor); void setIsServerlessMode(bool serverlessDomain); + void setIsInterstitialMode(bool interstialMode); void loadServerlessDomain(QUrl domainURL); void updateVerboseLogging(); @@ -624,6 +626,7 @@ private: QSet _keysPressed; bool _enableProcessOctreeThread; + bool _interstitialMode { true }; OctreePacketProcessor _octreeProcessor; EntityEditPacketSender _entityEditSender; diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index c57360b09f..0eadcc5b66 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -668,7 +668,7 @@ void AudioClient::stop() { void AudioClient::handleAudioEnvironmentDataPacket(QSharedPointer message) { - char bitset; + /*char bitset; message->readPrimitive(&bitset); bool hasReverb = oneAtBit(bitset, HAS_REVERB_BIT); @@ -680,11 +680,11 @@ void AudioClient::handleAudioEnvironmentDataPacket(QSharedPointer message) { - + /* if (message->getType() == PacketType::SilentAudioFrame) { _silentInbound.increment(); } else { @@ -709,7 +709,7 @@ void AudioClient::handleAudioDataPacket(QSharedPointer message) // Audio output must exist and be correctly set up if we're going to process received audio _receivedAudioStream.parseData(*message); #endif - } +}*/ } AudioClient::Gate::Gate(AudioClient* audioClient) : From 048196ec6fb2d56b319509c6dd2c2959e82a9135 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Thu, 2 Aug 2018 11:39:06 -0700 Subject: [PATCH 023/545] disble sending avatar and audio packets during interstitial mode --- interface/src/Application.cpp | 61 ++++++--- interface/src/Application.h | 1 + interface/src/avatar/AvatarManager.cpp | 6 +- interface/src/avatar/MyAvatar.cpp | 1 + libraries/audio-client/src/AudioClient.cpp | 152 ++++++++++----------- libraries/audio-client/src/AudioClient.h | 2 + 6 files changed, 125 insertions(+), 98 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b638c51342..bbce49b941 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1372,6 +1372,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo }); connect(this, &Application::activeDisplayPluginChanged, reinterpret_cast(audioScriptingInterface.data()), &scripting::Audio::onContextChanged); + connect(this, &Application::interstitialModeChanged, audioIO.data(), &AudioClient::setInterstitialStatus); } // Create the rendering engine. This can be slow on some machines due to lots of @@ -2252,6 +2253,25 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo // Preload Tablet sounds DependencyManager::get()->preloadSounds(); + connect(this, &Application::interstitialModeChanged, this, [this] (bool interstitialMode) { + if (!interstitialMode) { + DependencyManager::get()->negotiateAudioFormat(); + _queryExpiry = SteadyClock::now(); + if (_avatarOverrideUrl.isValid()) { + getMyAvatar()->useFullAvatarURL(_avatarOverrideUrl); + } + static const QUrl empty{}; + if (getMyAvatar()->getFullAvatarURLFromPreferences() != getMyAvatar()->cannonicalSkeletonModelURL(empty)) { + getMyAvatar()->resetFullAvatarURL(); + } + getMyAvatar()->markIdentityDataChanged(); + getMyAvatar()->resetLastSent(); + + // transmit a "sendAll" packet to the AvatarMixer we just connected to. + getMyAvatar()->sendAvatarDataPacket(true); + } + }); + _pendingIdleEvent = false; _pendingRenderEvent = false; @@ -3412,13 +3432,14 @@ bool Application::isServerlessMode() const { return false; } -bool Application::isInterstitialPage() { +bool Application::isInterstitialMode() const { return _interstitialMode; } -void Application::setInterstitialMode(bool interstitialMode) { +void Application::setIsInterstitialMode(bool interstitialMode) { if (_interstitialMode != interstitialMode) { _interstitialMode = interstitialMode; + emit interstitialModeChanged(_interstitialMode); } } @@ -5481,8 +5502,6 @@ static bool domainLoadingInProgress = false; void Application::update(float deltaTime) { PROFILE_RANGE_EX(app, __FUNCTION__, 0xffff0000, (uint64_t)_renderFrameCount + 1); - auto audioClient = DependencyManager::get(); - audioClient->setMuted(true); if (!_physicsEnabled) { if (!domainLoadingInProgress) { PROFILE_ASYNC_BEGIN(app, "Scene Loading", ""); @@ -5504,6 +5523,7 @@ void Application::update(float deltaTime) { // scene is ready to compute its collision shape. if (nearbyEntitiesAreReadyForPhysics() && getMyAvatar()->isReadyForPhysics()) { _physicsEnabled = true; + setIsInterstitialMode(false); getMyAvatar()->updateMotionBehaviorFromMenu(); } } @@ -5909,7 +5929,7 @@ void Application::update(float deltaTime) { // send packet containing downstream audio stats to the AudioMixer { quint64 sinceLastNack = now - _lastSendDownstreamAudioStats; - if (sinceLastNack > TOO_LONG_SINCE_LAST_SEND_DOWNSTREAM_AUDIO_STATS) { + if (sinceLastNack > TOO_LONG_SINCE_LAST_SEND_DOWNSTREAM_AUDIO_STATS && !isInterstitialMode()) { _lastSendDownstreamAudioStats = now; QMetaObject::invokeMethod(DependencyManager::get().data(), "sendDownstreamAudioStatsPacket", Qt::QueuedConnection); @@ -6072,21 +6092,23 @@ void Application::updateRenderArgs(float deltaTime) { } void Application::queryAvatars() { - auto avatarPacket = NLPacket::create(PacketType::AvatarQuery); - auto destinationBuffer = reinterpret_cast(avatarPacket->getPayload()); - unsigned char* bufferStart = destinationBuffer; + if (!isInterstitialMode()) { + auto avatarPacket = NLPacket::create(PacketType::AvatarQuery); + auto destinationBuffer = reinterpret_cast(avatarPacket->getPayload()); + unsigned char* bufferStart = destinationBuffer; - uint8_t numFrustums = (uint8_t)_conicalViews.size(); - memcpy(destinationBuffer, &numFrustums, sizeof(numFrustums)); - destinationBuffer += sizeof(numFrustums); + uint8_t numFrustums = (uint8_t)_conicalViews.size(); + memcpy(destinationBuffer, &numFrustums, sizeof(numFrustums)); + destinationBuffer += sizeof(numFrustums); - for (const auto& view : _conicalViews) { - destinationBuffer += view.serialize(destinationBuffer); + for (const auto& view : _conicalViews) { + destinationBuffer += view.serialize(destinationBuffer); + } + + avatarPacket->setPayloadSize(destinationBuffer - bufferStart); + + DependencyManager::get()->broadcastToNodes(std::move(avatarPacket), NodeSet() << NodeType::AvatarMixer); } - - avatarPacket->setPayloadSize(destinationBuffer - bufferStart); - - DependencyManager::get()->broadcastToNodes(std::move(avatarPacket), NodeSet() << NodeType::AvatarMixer); } @@ -6293,6 +6315,7 @@ void Application::clearDomainOctreeDetails() { qCDebug(interfaceapp) << "Clearing domain octree details..."; resetPhysicsReadyInformation(); + setIsInterstitialMode(true); _octreeServerSceneStats.withWriteLock([&] { _octreeServerSceneStats.clear(); @@ -6367,11 +6390,11 @@ void Application::nodeActivated(SharedNodePointer node) { _octreeQuery.incrementConnectionID(); } - if (node->getType() == NodeType::AudioMixer) { + if (node->getType() == NodeType::AudioMixer && !isInterstitialMode()) { DependencyManager::get()->negotiateAudioFormat(); } - if (node->getType() == NodeType::AvatarMixer) { + if (node->getType() == NodeType::AvatarMixer && !isInterstitialMode()) { _queryExpiry = SteadyClock::now(); // new avatar mixer, send off our identity packet on next update loop diff --git a/interface/src/Application.h b/interface/src/Application.h index c084c0033f..6bdfef78e1 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -328,6 +328,7 @@ signals: void activeDisplayPluginChanged(); void uploadRequest(QString path); + void interstitialModeChanged(bool interstitialMode); public slots: QVector pasteEntities(float x, float y, float z); diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index fab512f787..0fcc253f53 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -121,7 +121,7 @@ void AvatarManager::updateMyAvatar(float deltaTime) { quint64 now = usecTimestampNow(); quint64 dt = now - _lastSendAvatarDataTime; - if (dt > MIN_TIME_BETWEEN_MY_AVATAR_DATA_SENDS) { + if (dt > MIN_TIME_BETWEEN_MY_AVATAR_DATA_SENDS && !qApp->isInterstitialMode()) { // send head/hand data to the avatar mixer and voxel server PerformanceTimer perfTimer("send"); _myAvatar->sendAvatarDataPacket(); @@ -755,13 +755,13 @@ void AvatarManager::setAvatarSortCoefficient(const QString& name, const QScriptV QString currentSessionUUID = avatar->getSessionUUID().toString(); if (specificAvatarIdentifiers.isEmpty() || specificAvatarIdentifiers.contains(currentSessionUUID)) { QJsonObject thisAvatarPalData; - + auto myAvatar = DependencyManager::get()->getMyAvatar(); if (currentSessionUUID == myAvatar->getSessionUUID().toString()) { currentSessionUUID = ""; } - + thisAvatarPalData.insert("sessionUUID", currentSessionUUID); thisAvatarPalData.insert("sessionDisplayName", avatar->getSessionDisplayName()); thisAvatarPalData.insert("audioLoudness", avatar->getAudioLoudness()); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 98fbd8fea2..ec5ca903a0 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -2212,6 +2212,7 @@ void MyAvatar::setHasScriptedBlendshapes(bool hasScriptedBlendshapes) { // send a forced avatarData update to make sure the script can send neutal blendshapes on unload // without having to wait for the update loop, make sure _hasScriptedBlendShapes is still true // before sending the update, or else it won't send the neutal blendshapes to the receiving clients + sendAvatarDataPacket(true); } _hasScriptedBlendShapes = hasScriptedBlendshapes; diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 0eadcc5b66..a1487fa3ec 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -667,8 +667,7 @@ void AudioClient::stop() { } void AudioClient::handleAudioEnvironmentDataPacket(QSharedPointer message) { - - /*char bitset; + char bitset; message->readPrimitive(&bitset); bool hasReverb = oneAtBit(bitset, HAS_REVERB_BIT); @@ -680,11 +679,10 @@ void AudioClient::handleAudioEnvironmentDataPacket(QSharedPointer message) { - /* if (message->getType() == PacketType::SilentAudioFrame) { _silentInbound.increment(); } else { @@ -709,7 +707,7 @@ void AudioClient::handleAudioDataPacket(QSharedPointer message) // Audio output must exist and be correctly set up if we're going to process received audio _receivedAudioStream.parseData(*message); #endif -}*/ + } } AudioClient::Gate::Gate(AudioClient* audioClient) : @@ -1042,80 +1040,82 @@ void AudioClient::handleLocalEchoAndReverb(QByteArray& inputByteArray) { } void AudioClient::handleAudioInput(QByteArray& audioBuffer) { - if (_muted) { - _lastInputLoudness = 0.0f; - _timeSinceLastClip = 0.0f; - } else { - int16_t* samples = reinterpret_cast(audioBuffer.data()); - int numSamples = audioBuffer.size() / AudioConstants::SAMPLE_SIZE; - int numFrames = numSamples / (_isStereoInput ? AudioConstants::STEREO : AudioConstants::MONO); - - if (_isNoiseGateEnabled) { - // The audio gate includes DC removal - _audioGate->render(samples, samples, numFrames); - } else { - _audioGate->removeDC(samples, samples, numFrames); - } - - int32_t loudness = 0; - assert(numSamples < 65536); // int32_t loudness cannot overflow - bool didClip = false; - for (int i = 0; i < numSamples; ++i) { - const int32_t CLIPPING_THRESHOLD = (int32_t)(AudioConstants::MAX_SAMPLE_VALUE * 0.9f); - int32_t sample = std::abs((int32_t)samples[i]); - loudness += sample; - didClip |= (sample > CLIPPING_THRESHOLD); - } - _lastInputLoudness = (float)loudness / numSamples; - - if (didClip) { + if (!_interstitialMode) { + if (_muted) { + _lastInputLoudness = 0.0f; _timeSinceLastClip = 0.0f; - } else if (_timeSinceLastClip >= 0.0f) { - _timeSinceLastClip += (float)numSamples / (float)AudioConstants::SAMPLE_RATE; + } else { + int16_t* samples = reinterpret_cast(audioBuffer.data()); + int numSamples = audioBuffer.size() / AudioConstants::SAMPLE_SIZE; + int numFrames = numSamples / (_isStereoInput ? AudioConstants::STEREO : AudioConstants::MONO); + + if (_isNoiseGateEnabled) { + // The audio gate includes DC removal + _audioGate->render(samples, samples, numFrames); + } else { + _audioGate->removeDC(samples, samples, numFrames); + } + + int32_t loudness = 0; + assert(numSamples < 65536); // int32_t loudness cannot overflow + bool didClip = false; + for (int i = 0; i < numSamples; ++i) { + const int32_t CLIPPING_THRESHOLD = (int32_t)(AudioConstants::MAX_SAMPLE_VALUE * 0.9f); + int32_t sample = std::abs((int32_t)samples[i]); + loudness += sample; + didClip |= (sample > CLIPPING_THRESHOLD); + } + _lastInputLoudness = (float)loudness / numSamples; + + if (didClip) { + _timeSinceLastClip = 0.0f; + } else if (_timeSinceLastClip >= 0.0f) { + _timeSinceLastClip += (float)numSamples / (float)AudioConstants::SAMPLE_RATE; + } + + emit inputReceived(audioBuffer); } - emit inputReceived(audioBuffer); + emit inputLoudnessChanged(_lastInputLoudness); + + // state machine to detect gate opening and closing + bool audioGateOpen = (_lastInputLoudness != 0.0f); + bool openedInLastBlock = !_audioGateOpen && audioGateOpen; // the gate just opened + bool closedInLastBlock = _audioGateOpen && !audioGateOpen; // the gate just closed + _audioGateOpen = audioGateOpen; + + if (openedInLastBlock) { + emit noiseGateOpened(); + } else if (closedInLastBlock) { + emit noiseGateClosed(); + } + + // the codec must be flushed to silence before sending silent packets, + // so delay the transition to silent packets by one packet after becoming silent. + auto packetType = _shouldEchoToServer ? PacketType::MicrophoneAudioWithEcho : PacketType::MicrophoneAudioNoEcho; + if (!audioGateOpen && !closedInLastBlock) { + packetType = PacketType::SilentAudioFrame; + _silentOutbound.increment(); + } else { + _audioOutbound.increment(); + } + + Transform audioTransform; + audioTransform.setTranslation(_positionGetter()); + audioTransform.setRotation(_orientationGetter()); + + QByteArray encodedBuffer; + if (_encoder) { + _encoder->encode(audioBuffer, encodedBuffer); + } else { + encodedBuffer = audioBuffer; + } + + emitAudioPacket(encodedBuffer.data(), encodedBuffer.size(), _outgoingAvatarAudioSequenceNumber, _isStereoInput, + audioTransform, avatarBoundingBoxCorner, avatarBoundingBoxScale, + packetType, _selectedCodecName); + _stats.sentPacket(); } - - emit inputLoudnessChanged(_lastInputLoudness); - - // state machine to detect gate opening and closing - bool audioGateOpen = (_lastInputLoudness != 0.0f); - bool openedInLastBlock = !_audioGateOpen && audioGateOpen; // the gate just opened - bool closedInLastBlock = _audioGateOpen && !audioGateOpen; // the gate just closed - _audioGateOpen = audioGateOpen; - - if (openedInLastBlock) { - emit noiseGateOpened(); - } else if (closedInLastBlock) { - emit noiseGateClosed(); - } - - // the codec must be flushed to silence before sending silent packets, - // so delay the transition to silent packets by one packet after becoming silent. - auto packetType = _shouldEchoToServer ? PacketType::MicrophoneAudioWithEcho : PacketType::MicrophoneAudioNoEcho; - if (!audioGateOpen && !closedInLastBlock) { - packetType = PacketType::SilentAudioFrame; - _silentOutbound.increment(); - } else { - _audioOutbound.increment(); - } - - Transform audioTransform; - audioTransform.setTranslation(_positionGetter()); - audioTransform.setRotation(_orientationGetter()); - - QByteArray encodedBuffer; - if (_encoder) { - _encoder->encode(audioBuffer, encodedBuffer); - } else { - encodedBuffer = audioBuffer; - } - - emitAudioPacket(encodedBuffer.data(), encodedBuffer.size(), _outgoingAvatarAudioSequenceNumber, _isStereoInput, - audioTransform, avatarBoundingBoxCorner, avatarBoundingBoxScale, - packetType, _selectedCodecName); - _stats.sentPacket(); } void AudioClient::handleMicAudioInput() { @@ -2017,7 +2017,7 @@ void AudioClient::loadSettings() { _receivedAudioStream.setDynamicJitterBufferEnabled(dynamicJitterBufferEnabled.get()); _receivedAudioStream.setStaticJitterBufferFrames(staticJitterBufferFrames.get()); - qCDebug(audioclient) << "---- Initializing Audio Client ----"; + auto codecPlugins = PluginManager::getInstance()->getCodecPlugins(); for (auto& plugin : codecPlugins) { qCDebug(audioclient) << "Codec available:" << plugin->getName(); diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index 9ee7bcfeba..b665f85a13 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -188,6 +188,7 @@ public slots: void handleRecordedAudioInput(const QByteArray& audio); void reset(); void audioMixerKilled(); + void setInterstitialStatus(bool interstitialMode) { _interstitialMode = interstitialMode; } void setMuted(bool muted, bool emitSignal = true); bool isMuted() { return _muted; } @@ -417,6 +418,7 @@ private: QVector _activeLocalAudioInjectors; bool _isPlayingBackRecording { false }; + bool _interstitialMode { true }; CodecPluginPointer _codec; QString _selectedCodecName; From b9cfbfb3beae4d3ed0070d91e1bdac10c540a832 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Fri, 3 Aug 2018 09:59:21 -0700 Subject: [PATCH 024/545] adding interstitial page file to default sctipts --- interface/src/Application.cpp | 4 +- libraries/audio-client/src/AudioClient.cpp | 2 +- scripts/defaultScripts.js | 3 +- scripts/system/interstitialPage.js | 414 +++++++++++++++++++++ 4 files changed, 419 insertions(+), 4 deletions(-) create mode 100644 scripts/system/interstitialPage.js diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index bbce49b941..bbe107e69e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3713,7 +3713,7 @@ void Application::keyPressEvent(QKeyEvent* event) { _controllerScriptingInterface->emitKeyPressEvent(event); // send events to any registered scripts // if one of our scripts have asked to capture this event, then stop processing it - if (_controllerScriptingInterface->isKeyCaptured(event)) { + if (_controllerScriptingInterface->isKeyCaptured(event) || isInterstitialMode()) { return; } @@ -5603,7 +5603,7 @@ void Application::update(float deltaTime) { // Transfer the user inputs to the driveKeys // FIXME can we drop drive keys and just have the avatar read the action states directly? myAvatar->clearDriveKeys(); - if (_myCamera.getMode() != CAMERA_MODE_INDEPENDENT) { + if (_myCamera.getMode() != CAMERA_MODE_INDEPENDENT && !isInterstitialMode()) { if (!_controllerScriptingInterface->areActionsCaptured() && _myCamera.getMode() != CAMERA_MODE_MIRROR) { myAvatar->setDriveKey(MyAvatar::TRANSLATE_Z, -1.0f * userInputMapper->getActionState(controller::Action::TRANSLATE_Z)); myAvatar->setDriveKey(MyAvatar::TRANSLATE_Y, userInputMapper->getActionState(controller::Action::TRANSLATE_Y)); diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index a1487fa3ec..380d978fb1 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -2017,7 +2017,7 @@ void AudioClient::loadSettings() { _receivedAudioStream.setDynamicJitterBufferEnabled(dynamicJitterBufferEnabled.get()); _receivedAudioStream.setStaticJitterBufferFrames(staticJitterBufferFrames.get()); - + qCDebug(audioclient) << "---- Initializing Audio Client ----"; auto codecPlugins = PluginManager::getInstance()->getCodecPlugins(); for (auto& plugin : codecPlugins) { qCDebug(audioclient) << "Codec available:" << plugin->getName(); diff --git a/scripts/defaultScripts.js b/scripts/defaultScripts.js index b275660c0f..662120be34 100644 --- a/scripts/defaultScripts.js +++ b/scripts/defaultScripts.js @@ -31,7 +31,8 @@ var DEFAULT_SCRIPTS_COMBINED = [ "system/dialTone.js", "system/firstPersonHMD.js", "system/tablet-ui/tabletUI.js", - "system/emote.js" + "system/emote.js", + "system/interstitialpage" ]; var DEFAULT_SCRIPTS_SEPARATE = [ "system/controllers/controllerScripts.js", diff --git a/scripts/system/interstitialPage.js b/scripts/system/interstitialPage.js new file mode 100644 index 0000000000..af80e94605 --- /dev/null +++ b/scripts/system/interstitialPage.js @@ -0,0 +1,414 @@ +// +// interstitialPage.js +// scripts/system +// +// Created by Dante Ruiz on 08/02/2018. +// Copyright 2012 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +/* global Script, Controller, Overlays, Quat, MyAvatar, Entities, print, Vec3, AddressManager, Render, Window, Toolbars, + Camera, HMD*/ + +(function() { + var MAX_X_SIZE = 3; + var isVisible = true; + var defaultOffset = 1.5; + var hifi = "HighFidelity"; + var VOLUME = 0.4; + var tune = SoundCache.getSound("http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/crystals_and_voices.wav"); + var sample = null; + var MAX_LEFT_MARGIN = 1.9; + var INNER_CIRCLE_WIDTH = 4.7; + var DESTINATION_CARD_Y_OFFSET = 2; + var DEFAULT_TONE_MAPPING_EXPOSURE = 0.0; + var MIN_TONE_MAPPING_EXPOSURE = -5.0; + var SYSTEM_TOOL_BAR = "com.highfidelity.interface.toolbar.system"; + var MAX_ELAPSED_TIME = 5 * 1000; // time in ms + function isInFirstPerson() { + return (Camera.mode === "first person"); + } + + var toolbar = Toolbars.getToolbar(SYSTEM_TOOL_BAR); + var renderViewTask = Render.getConfig("RenderMainView"); + + var domainHostnameMap = { + eschatology: "Seth Alves", + blue: "Sam Cake", + thepines: "Roxie", + "dev-mobile": "HighFidelity", + "dev-mobile-master": "HighFidelity", + portalarium: "Bijou", + porange: "Caitlyn", + rust: hifi, + start: hifi, + miimusic: "Madysyn", + codex: "FluffyJenkins", + zaru: hifi, + help: hifi, + therealoasis: "Caitlyn", + vrmacy: "budgiebeats", + niccage: "OneLisa", + impromedia: "GeorgeDeac", + nest: "budgiebeats", + gabworld: "LeeGab", + vrtv: "GeoorgeDeac", + burrow: "budgiebeats", + leftcoast: "Lurks", + lazybones: "LazybonesJurassic", + skyriver: "Chamberlain", + chapel: "www.livin.today", + "hi-studio": hifi, + luskan: "jyoum", + arcadiabay: "Aitolda", + chime: hifi, + standupnow: "diva", + avreng: "GeorgeDeac", + atlas: "rocklin_guy", + steamedhams: "Alan_", + banff: hifi, + operahouse: hifi, + bankofhighfidelity: hifi, + tutorial: "WadeWatts", + nightsky: hifi, + garageband: hifi, + painting: hifi, + windwaker: "bijou", + fumbleland: "Lpasca", + monolith: "Nik", + bijou: "bijou", + morty: "bijou", + "hifiqa-rc-bots": hifi, + fightnight: hifi, + spirited: "Alan_", + "desert-oasis": "ryan", + springfield: "Alan_", + hall: "ryan", + "national-park": "ryan", + vector: "Nik", + bodymart: hifi, + "medievil-village": "ryan", + "villains-lair": "ryan", + "island-breeze": "ryan", + "classy-apartment": "ryan", + voxel: "FlameSoulis", + virtuoso: "noahglaseruc", + avatarisland: hifi, + ioab: "rocklin_guy", + tamait: "rocklin_guy", + konshulabs: "Konshu", + epic: "philip", + poopsburg: "Caitlyn", + east: hifi, + glitched: hifi, + calartsim: hifi, + calarts: hifi, + livin: "rocklin_guy", + fightclub: "philip", + thefactory: "whyroc", + wothal: "Alezia.Kurdis", + udacity: hifi, + json: "WadeWatts", + anonymous: "darlingnotin", + maker: hifi, + elisa: "elisahifi", + volxeltopia: hifi, + cupcake: hifi, + minigolf: hifi, + workshop: hifi, + vankh: "Alezia.Kurdis", + "the-crash-site": "WolfGang", + jjv360: "jjv3600", + distributed2: hifi, + anny: hifi, + university: hifi, + ludus: hifi, + stepford: "darlingnotin", + thespot: hifi + }; + + // Tips have a character limit of 69 + var userTips = [ + "Tip: Visit TheSpot to explore featured domains!", + "Tip: Visit our docs online to learn more about scripting!", + "Tip: Don't want others invading your personal space? Turn on the Bubble!", + "Tip: Want to make a friend? Shake hands with them in VR!", + "Tip: Enjoy live music? Visit Rust to dance your heart out!", + "Tip: Have you visited BodyMart to check out the new avatars recently?", + "Tip: Use the Create app to import models and create custom entities.", + "Tip: We're open source! Feel free to contribute to our code on GitHub!", + "Tip: What emotes have you used in the Emote app?", + "Tip: Take and share your snapshots with the everyone using the Snap app.", + "Tip: Did you know you can show websites in-world by creating a web entity?", + "Tip: Find out more information about domains by visiting our website!", + "Tip: Did you know you can get cool new apps from the Marketplace?", + "Tip: Print your snapshots from the Snap app to share with others!", + "Tip: Log in to make friends, visit new domains, and save avatars!" + ]; + + var loadingSphereID = Overlays.addOverlay("model", { + name: "Loading-Sphere", + position: Vec3.sum(Vec3.sum(MyAvatar.position, {x: 0.0, y: -1.0, z: 0.0}), Vec3.multiplyQbyV(MyAvatar.orientation, {x: 0, y: 0.95, z: 0})), + orientation: Quat.multiply(Quat.fromVec3Degrees({x: 0, y: 180, z: 0}), MyAvatar.orientation), + url: "http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/black-sphere.fbx", + dimensions: { x: 20, y: 20, z: 20 }, + alpha: 1, + visible: isVisible, + ignoreRayIntersection: true, + drawInFront: true, + grabbable: false + }); + + + var domainName = ""; + var domainNameTextID = Overlays.addOverlay("text3d", { + name: "Loading-Destination-Card-Text", + localPosition: { x: 0.0, y: DESTINATION_CARD_Y_OFFSET + 0.8, z: 5.45 }, + text: domainName, + textAlpha: 1, + backgroundAlpha: 0, + lineHeight: 0.42, + visible: isVisible, + ignoreRayIntersection: true, + drawInFront: true, + grabbable: false, + localOrientation: Quat.fromVec3Degrees({ x: 0, y: 180, z: 0 }), + parentID: loadingSphereID + }); + + var hostName = ""; + + var domainHostname = Overlays.addOverlay("text3d", { + name: "Loading-Hostname", + localPosition: { x: 0.0, y: DESTINATION_CARD_Y_OFFSET + 0.32, z: 5.45 }, + text: hostName, + textAlpha: 1, + backgroundAlpha: 0, + lineHeight: 0.13, + visible: isVisible, + ignoreRayIntersection: true, + drawInFront: true, + grabbable: false, + localOrientation: Quat.fromVec3Degrees({ x: 0, y: 180, z: 0 }), + parentID: loadingSphereID + }); + + var toolTip = ""; + + var domainToolTip = Overlays.addOverlay("text3d", { + name: "Loading-Tooltip", + localPosition: { x: 0.0 , y: DESTINATION_CARD_Y_OFFSET - 1.6, z: 5.45 }, + text: toolTip, + textAlpha: 1, + backgroundAlpha: 0, + lineHeight: 0.13, + visible: isVisible, + ignoreRayIntersection: true, + drawInFront: true, + grabbable: false, + localOrientation: Quat.fromVec3Degrees({ x: 0, y: 180, z: 0 }), + parentID: loadingSphereID + }); + + var loadingToTheSpotID = Overlays.addOverlay("image3d", { + name: "Loading-Destination-Card-Text", + localPosition: { x: 0.0 , y: DESTINATION_CARD_Y_OFFSET - 1.8, z: 5.45 }, + url: "http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/goTo_button.png", + alpha: 1, + dimensions: { x: 1.2, y: 0.6}, + visible: isVisible, + emissive: true, + ignoreRayIntersection: false, + drawInFront: true, + grabbable: false, + localOrientation: Quat.fromVec3Degrees({ x: 0.0, y: 180.0, z: 0.0 }), + parentID: loadingSphereID + }); + + var loadingBarPlacard = Overlays.addOverlay("image3d", { + name: "Loading-Bar-Placard", + localPosition: { x: 0.0 , y: DESTINATION_CARD_Y_OFFSET - 0.99, z: 5.45 }, + url: "http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/loadingBar_placard.png", + alpha: 1, + dimensions: { x: 4, y: 2.8}, + visible: isVisible, + emissive: true, + ignoreRayIntersection: false, + drawInFront: true, + grabbable: false, + localOrientation: Quat.fromVec3Degrees({ x: 0.0, y: 180.0, z: 0.0 }), + parentID: loadingSphereID + }); + + var loadingBarProgress = Overlays.addOverlay("image3d", { + name: "Loading-Bar-Progress", + localPosition: { x: 0.0 , y: DESTINATION_CARD_Y_OFFSET - 0.99, z: 5.45 }, + url: "http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/loadingBar_progress.png", + alpha: 1, + dimensions: { x: 4, y: 2.8}, + visible: isVisible, + emissive: true, + ignoreRayIntersection: false, + drawInFront: true, + grabbable: false, + localOrientation: Quat.fromVec3Degrees({ x: 0.0, y: 180.0, z: 0.0 }), + parentID: loadingSphereID + }); + + var TARGET_UPDATE_HZ = 60; // 50hz good enough, but we're using update + var BASIC_TIMER_INTERVAL_MS = 1000 / TARGET_UPDATE_HZ; + var timerset = false; + var lastInterval = Date.now(); + var timeElapsed = 0; + + + function getLeftMargin(overlayID, text) { + var textSize = Overlays.textSize(overlayID, text); + var sizeDifference = ((INNER_CIRCLE_WIDTH - textSize.width) / 2); + var leftMargin = -(MAX_LEFT_MARGIN - sizeDifference); + return leftMargin; + } + + + function domainChanged(domain) { + var name = AddressManager.placename; + domainName = name.charAt(0).toUpperCase() + name.slice(1); + var domainNameLeftMargin = getLeftMargin(domainNameTextID, domainName); + var textProperties = { + text: domainName, + leftMargin: domainNameLeftMargin + }; + + var BY = "by "; + var host = domainHostnameMap[location.placename]; + var text = BY + host; + var hostLeftMargin = getLeftMargin(domainHostname, text); + var hostnameProperties = { + text: BY + host, + leftMargin: hostLeftMargin + }; + + var randomIndex = Math.floor(Math.random() * userTips.length); + var tip = userTips[randomIndex]; + var tipLeftMargin = getLeftMargin(domainToolTip, tip); + var toolTipProperties = { + text: tip, + leftMargin: tipLeftMargin + }; + + var myAvatarDirection = Vec3.UNIT_NEG_Z; + var cardDirectionPrime = {x: 0 , y: 0, z: 5.5}; + var rotationDelta = Quat.rotationBetween(cardDirectionPrime, myAvatarDirection); + var overlayRotation = Quat.multiply(MyAvatar.orientation, rotationDelta); + var mainSphereProperties = { + orientation: overlayRotation + }; + + Overlays.editOverlay(loadingSphereID, mainSphereProperties); + Overlays.editOverlay(domainNameTextID, textProperties); + Overlays.editOverlay(domainHostname, hostnameProperties); + Overlays.editOverlay(domainToolTip, toolTipProperties); + } + + var THE_PLACE = "hifi://TheSpot"; + function clickedOnOverlay(overlayID, event) { + print(overlayID + " other: " + loadingToTheSpotID); + print(event.button === "Primary"); + if (loadingToTheSpotID === overlayID) { + if (timerset) { + timeElapsed = 0; + } + AddressManager.handleLookupString(THE_PLACE); + } + } + var previousCameraMode = Camera.mode; + var previousPhysicsStatus = 99999; + + function updateOverlays(physicsEnabled) { + var properties = { + visible: !physicsEnabled + }; + + var myAvatarDirection = Vec3.UNIT_NEG_Z; + var cardDirectionPrime = {x: 0 , y: 0, z: 5.5}; + var rotationDelta = Quat.rotationBetween(cardDirectionPrime, myAvatarDirection); + var overlayRotation = Quat.multiply(MyAvatar.orientation, rotationDelta); + var mainSphereProperties = { + visible: !physicsEnabled, + orientation: overlayRotation + }; + + if (!HMD.active) { + toolbar.writeProperty("visible", physicsEnabled); + MyAvatar.headOrientation = Quat.multiply(Quat.cancelOutRollAndPitch(MyAvatar.headOrientation), Quat.fromPitchYawRollDegrees(2.5, 0, 0)); + } + + renderViewTask.getConfig("LightingModel")["enableAmbientLight"] = physicsEnabled; + renderViewTask.getConfig("LightingModel")["enableDirectionalLight"] = physicsEnabled; + renderViewTask.getConfig("LightingModel")["enablePointLight"] = physicsEnabled; + Overlays.editOverlay(loadingSphereID, mainSphereProperties); + Overlays.editOverlay(loadingToTheSpotID, properties); + Overlays.editOverlay(domainNameTextID, properties); + Overlays.editOverlay(domainHostname, properties); + Overlays.editOverlay(domainToolTip, properties); + Overlays.editOverlay(loadingBarPlacard, properties); + Overlays.editOverlay(loadingBarProgress, properties); + } + + function update() { + var physicsEnabled = Window.isPhysicsEnabled(); + var thisInterval = Date.now(); + var deltaTime = (thisInterval - lastInterval); + lastInterval = thisInterval; + if (physicsEnabled !== previousPhysicsStatus) { + if (!physicsEnabled && !timerset) { + updateOverlays(physicsEnabled); + sample = Audio.playSound(tune, { + localOnly: true, + position: MyAvatar.headPosition, + volume: VOLUME + }); + timeElapsed = 0; + timerset = true; + } + previousPhysicsStatus = physicsEnabled; + } + + if (timerset) { + timeElapsed += deltaTime; + if (timeElapsed >= MAX_ELAPSED_TIME) { + updateOverlays(true); + sample.stop(); + sample = null; + timerset = false; + } + + } + + Overlays.editOverlay(loadingSphereID, { + position: Vec3.sum(Vec3.sum(MyAvatar.position, {x: 0.0, y: -1.7, z: 0.0}), Vec3.multiplyQbyV(MyAvatar.orientation, {x: 0, y: 0.95, z: 0})) + }); + Script.setTimeout(update, BASIC_TIMER_INTERVAL_MS); + } + + Script.setTimeout(update, BASIC_TIMER_INTERVAL_MS); + Overlays.mouseReleaseOnOverlay.connect(clickedOnOverlay); + Window.domainChanged.connect(domainChanged); + + function cleanup() { + Overlays.deleteOverlay(loadingSphereID); + Overlays.deleteOverlay(loadingToTheSpotID); + Overlays.deleteOverlay(domainNameTextID); + Overlays.deleteOverlay(domainHostname); + Overlays.deleteOverlay(domainToolTip); + Overlays.deleteOverlay(loadingBarPlacard); + Overlays.deleteOverlay(loadingBarProgress); + try { + } catch (e) { + } + } + + Script.scriptEnding.connect(cleanup); +}()); From a2717e2efa9af8405b496b5a91cf653dacdd62ac Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Fri, 3 Aug 2018 10:47:20 -0700 Subject: [PATCH 025/545] editing interstitialPage.js --- scripts/defaultScripts.js | 2 +- scripts/system/interstitialPage.js | 111 +---------------------------- 2 files changed, 4 insertions(+), 109 deletions(-) diff --git a/scripts/defaultScripts.js b/scripts/defaultScripts.js index 662120be34..a11ec98c40 100644 --- a/scripts/defaultScripts.js +++ b/scripts/defaultScripts.js @@ -32,7 +32,7 @@ var DEFAULT_SCRIPTS_COMBINED = [ "system/firstPersonHMD.js", "system/tablet-ui/tabletUI.js", "system/emote.js", - "system/interstitialpage" + "system/interstitialPage.js" ]; var DEFAULT_SCRIPTS_SEPARATE = [ "system/controllers/controllerScripts.js", diff --git a/scripts/system/interstitialPage.js b/scripts/system/interstitialPage.js index af80e94605..f90256b964 100644 --- a/scripts/system/interstitialPage.js +++ b/scripts/system/interstitialPage.js @@ -16,119 +16,18 @@ var MAX_X_SIZE = 3; var isVisible = true; var defaultOffset = 1.5; - var hifi = "HighFidelity"; var VOLUME = 0.4; var tune = SoundCache.getSound("http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/crystals_and_voices.wav"); var sample = null; var MAX_LEFT_MARGIN = 1.9; var INNER_CIRCLE_WIDTH = 4.7; var DESTINATION_CARD_Y_OFFSET = 2; - var DEFAULT_TONE_MAPPING_EXPOSURE = 0.0; - var MIN_TONE_MAPPING_EXPOSURE = -5.0; var SYSTEM_TOOL_BAR = "com.highfidelity.interface.toolbar.system"; var MAX_ELAPSED_TIME = 5 * 1000; // time in ms - function isInFirstPerson() { - return (Camera.mode === "first person"); - } var toolbar = Toolbars.getToolbar(SYSTEM_TOOL_BAR); var renderViewTask = Render.getConfig("RenderMainView"); - var domainHostnameMap = { - eschatology: "Seth Alves", - blue: "Sam Cake", - thepines: "Roxie", - "dev-mobile": "HighFidelity", - "dev-mobile-master": "HighFidelity", - portalarium: "Bijou", - porange: "Caitlyn", - rust: hifi, - start: hifi, - miimusic: "Madysyn", - codex: "FluffyJenkins", - zaru: hifi, - help: hifi, - therealoasis: "Caitlyn", - vrmacy: "budgiebeats", - niccage: "OneLisa", - impromedia: "GeorgeDeac", - nest: "budgiebeats", - gabworld: "LeeGab", - vrtv: "GeoorgeDeac", - burrow: "budgiebeats", - leftcoast: "Lurks", - lazybones: "LazybonesJurassic", - skyriver: "Chamberlain", - chapel: "www.livin.today", - "hi-studio": hifi, - luskan: "jyoum", - arcadiabay: "Aitolda", - chime: hifi, - standupnow: "diva", - avreng: "GeorgeDeac", - atlas: "rocklin_guy", - steamedhams: "Alan_", - banff: hifi, - operahouse: hifi, - bankofhighfidelity: hifi, - tutorial: "WadeWatts", - nightsky: hifi, - garageband: hifi, - painting: hifi, - windwaker: "bijou", - fumbleland: "Lpasca", - monolith: "Nik", - bijou: "bijou", - morty: "bijou", - "hifiqa-rc-bots": hifi, - fightnight: hifi, - spirited: "Alan_", - "desert-oasis": "ryan", - springfield: "Alan_", - hall: "ryan", - "national-park": "ryan", - vector: "Nik", - bodymart: hifi, - "medievil-village": "ryan", - "villains-lair": "ryan", - "island-breeze": "ryan", - "classy-apartment": "ryan", - voxel: "FlameSoulis", - virtuoso: "noahglaseruc", - avatarisland: hifi, - ioab: "rocklin_guy", - tamait: "rocklin_guy", - konshulabs: "Konshu", - epic: "philip", - poopsburg: "Caitlyn", - east: hifi, - glitched: hifi, - calartsim: hifi, - calarts: hifi, - livin: "rocklin_guy", - fightclub: "philip", - thefactory: "whyroc", - wothal: "Alezia.Kurdis", - udacity: hifi, - json: "WadeWatts", - anonymous: "darlingnotin", - maker: hifi, - elisa: "elisahifi", - volxeltopia: hifi, - cupcake: hifi, - minigolf: hifi, - workshop: hifi, - vankh: "Alezia.Kurdis", - "the-crash-site": "WolfGang", - jjv360: "jjv3600", - distributed2: hifi, - anny: hifi, - university: hifi, - ludus: hifi, - stepford: "darlingnotin", - thespot: hifi - }; - // Tips have a character limit of 69 var userTips = [ "Tip: Visit TheSpot to explore featured domains!", @@ -282,11 +181,10 @@ }; var BY = "by "; - var host = domainHostnameMap[location.placename]; - var text = BY + host; + var text = BY var hostLeftMargin = getLeftMargin(domainHostname, text); var hostnameProperties = { - text: BY + host, + text: BY, leftMargin: hostLeftMargin }; @@ -323,7 +221,7 @@ AddressManager.handleLookupString(THE_PLACE); } } - var previousCameraMode = Camera.mode; + var previousPhysicsStatus = 99999; function updateOverlays(physicsEnabled) { @@ -405,9 +303,6 @@ Overlays.deleteOverlay(domainToolTip); Overlays.deleteOverlay(loadingBarPlacard); Overlays.deleteOverlay(loadingBarProgress); - try { - } catch (e) { - } } Script.scriptEnding.connect(cleanup); From 237762620316fb48c7ea2ec779c0e9775ef6ac88 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Tue, 29 May 2018 13:22:20 -0700 Subject: [PATCH 026/545] exposing physics progress --- interface/src/Application.cpp | 5 +++++ interface/src/Application.h | 5 +++++ .../src/scripting/WindowScriptingInterface.cpp | 13 +++++++++++++ interface/src/scripting/WindowScriptingInterface.h | 4 ++++ 4 files changed, 27 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 12dbf823b3..496c133aeb 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5301,6 +5301,7 @@ void Application::resetPhysicsReadyInformation() { _fullSceneCounterAtLastPhysicsCheck = 0; _nearbyEntitiesCountAtLastPhysicsCheck = 0; _nearbyEntitiesStabilityCount = 0; + _nearbyEntitiesReadyCount = 0; _physicsEnabled = false; } @@ -6546,6 +6547,7 @@ bool Application::nearbyEntitiesAreReadyForPhysics() { _nearbyEntitiesCountAtLastPhysicsCheck = nearbyCount; const uint32_t MINIMUM_NEARBY_ENTITIES_STABILITY_COUNT = 3; + uint32_t readyNearbyEntities = 0; if (_nearbyEntitiesStabilityCount >= MINIMUM_NEARBY_ENTITIES_STABILITY_COUNT) { // We've seen the same number of nearby entities for several stats packets in a row. assume we've got all // the local entities. @@ -6555,8 +6557,11 @@ bool Application::nearbyEntitiesAreReadyForPhysics() { HIFI_FCDEBUG(interfaceapp(), "Physics disabled until entity loads: " << entity->getID() << entity->getName()); // don't break here because we want all the relevant entities to start their downloads result = false; + } else { + readyNearbyEntities++; } } + _nearbyEntitiesReadyCount = readyNearbyEntities; return result; } return false; diff --git a/interface/src/Application.h b/interface/src/Application.h index 6bdfef78e1..88aea0379f 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -224,6 +224,10 @@ public: void setHmdTabletBecomesToolbarSetting(bool value); bool getPreferStylusOverLaser() { return _preferStylusOverLaserSetting.get(); } void setPreferStylusOverLaser(bool value); + + uint32_t getEntitiesStabilityCount() { return _nearbyEntitiesStabilityCount; } + uint32_t getNearbyEntitiesReadyCount() { return _nearbyEntitiesReadyCount; } + uint32_t getNearbyEntitiesCount() { return _nearbyEntitiesCountAtLastPhysicsCheck; } // FIXME: Remove setting completely or make available through JavaScript API? //bool getPreferAvatarFingerOverStylus() { return _preferAvatarFingerOverStylusSetting.get(); } bool getPreferAvatarFingerOverStylus() { return false; } @@ -723,6 +727,7 @@ private: uint32_t _fullSceneCounterAtLastPhysicsCheck { 0 }; // _fullSceneReceivedCounter last time we checked physics ready uint32_t _nearbyEntitiesCountAtLastPhysicsCheck { 0 }; // how many in-range entities last time we checked physics ready uint32_t _nearbyEntitiesStabilityCount { 0 }; // how many times has _nearbyEntitiesCountAtLastPhysicsCheck been the same + uint32_t _nearbyEntitiesReadyCount { 0 }; quint64 _lastPhysicsCheckTime { usecTimestampNow() }; // when did we last check to see if physics was ready bool _keyboardDeviceHasFocus { true }; diff --git a/interface/src/scripting/WindowScriptingInterface.cpp b/interface/src/scripting/WindowScriptingInterface.cpp index ba86925581..965e183023 100644 --- a/interface/src/scripting/WindowScriptingInterface.cpp +++ b/interface/src/scripting/WindowScriptingInterface.cpp @@ -584,3 +584,16 @@ void WindowScriptingInterface::onMessageBoxSelected(int button) { _messageBoxes.remove(id); } } + + +int WindowScriptingInterface::getPhysicsNearbyEntitiesReadyCount() { + return qApp->getNearbyEntitiesReadyCount(); +} + +int WindowScriptingInterface::getPhysicsNearbyEntitiesStabilityCount() { + return qApp->getEntitiesStabilityCount(); +} + +int WindowScriptingInterface::getPhysicsNearbyEntitiesCount() { + return qApp->getNearbyEntitiesCount(); +} diff --git a/interface/src/scripting/WindowScriptingInterface.h b/interface/src/scripting/WindowScriptingInterface.h index 77895e0e76..035dcae9d0 100644 --- a/interface/src/scripting/WindowScriptingInterface.h +++ b/interface/src/scripting/WindowScriptingInterface.h @@ -561,6 +561,10 @@ public slots: */ void closeMessageBox(int id); + int getPhysicsNearbyEntitiesReadyCount(); + int getPhysicsNearbyEntitiesStabilityCount(); + int getPhysicsNearbyEntitiesCount(); + private slots: void onWindowGeometryChanged(const QRect& geometry); void onMessageBoxSelected(int button); From 6a4a56cee38aa3dc14a0ac50ab72f7000a33055d Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Mon, 6 Aug 2018 17:42:21 -0700 Subject: [PATCH 027/545] imporving the interstitial page script --- interface/src/Application.cpp | 1 + .../scripting/WindowScriptingInterface.cpp | 3 + .../src/scripting/WindowScriptingInterface.h | 3 + interface/src/ui/Stats.cpp | 4 + scripts/defaultScripts.js | 4 +- scripts/system/interstitialPage.js | 169 ++++++++++-------- 6 files changed, 108 insertions(+), 76 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ac14e2d636..a594756a80 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3458,6 +3458,7 @@ bool Application::isInterstitialMode() const { void Application::setIsInterstitialMode(bool interstitialMode) { if (_interstitialMode != interstitialMode) { + qDebug() << "-------> interstitial mode changed: " << _interstitialMode << " ------------> "; _interstitialMode = interstitialMode; emit interstitialModeChanged(_interstitialMode); } diff --git a/interface/src/scripting/WindowScriptingInterface.cpp b/interface/src/scripting/WindowScriptingInterface.cpp index 965e183023..68be55f88a 100644 --- a/interface/src/scripting/WindowScriptingInterface.cpp +++ b/interface/src/scripting/WindowScriptingInterface.cpp @@ -53,6 +53,9 @@ WindowScriptingInterface::WindowScriptingInterface() { }); connect(qApp->getWindow(), &MainWindow::windowGeometryChanged, this, &WindowScriptingInterface::onWindowGeometryChanged); + connect(qApp, &Application::interstitialModeChanged, [this] (bool interstitialStatus) { + emit interstitialStatusChanged(interstitialStatus); + }); } WindowScriptingInterface::~WindowScriptingInterface() { diff --git a/interface/src/scripting/WindowScriptingInterface.h b/interface/src/scripting/WindowScriptingInterface.h index 035dcae9d0..7b0b6435f7 100644 --- a/interface/src/scripting/WindowScriptingInterface.h +++ b/interface/src/scripting/WindowScriptingInterface.h @@ -746,6 +746,9 @@ signals: */ void geometryChanged(QRect geometry); + + void interstitialStatusChanged(bool intersititalMode); + private: QString getPreviousBrowseLocation() const; void setPreviousBrowseLocation(const QString& location); diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index 6bb615948c..991dee9980 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -105,6 +105,10 @@ extern std::atomic DECIMATED_TEXTURE_COUNT; extern std::atomic RECTIFIED_TEXTURE_COUNT; void Stats::updateStats(bool force) { + + if (qApp->isInterstitialMode()) { + return; + } QQuickItem* parent = parentItem(); if (!force) { if (!Menu::getInstance()->isOptionChecked(MenuOption::Stats)) { diff --git a/scripts/defaultScripts.js b/scripts/defaultScripts.js index a11ec98c40..31510831c8 100644 --- a/scripts/defaultScripts.js +++ b/scripts/defaultScripts.js @@ -31,11 +31,11 @@ var DEFAULT_SCRIPTS_COMBINED = [ "system/dialTone.js", "system/firstPersonHMD.js", "system/tablet-ui/tabletUI.js", - "system/emote.js", - "system/interstitialPage.js" + "system/emote.js" ]; var DEFAULT_SCRIPTS_SEPARATE = [ "system/controllers/controllerScripts.js", + "system/interstitialPage.js" //"system/chat.js" ]; diff --git a/scripts/system/interstitialPage.js b/scripts/system/interstitialPage.js index f90256b964..6960272e11 100644 --- a/scripts/system/interstitialPage.js +++ b/scripts/system/interstitialPage.js @@ -13,9 +13,11 @@ Camera, HMD*/ (function() { - var MAX_X_SIZE = 3; - var isVisible = true; - var defaultOffset = 1.5; + var MAX_X_SIZE = 5; + var EPSILON = 0.25; + var isVisible = false; + var STABILITY = 3.0; + var defaultOffset = -0.5; var VOLUME = 0.4; var tune = SoundCache.getSound("http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/crystals_and_voices.wav"); var sample = null; @@ -50,14 +52,15 @@ var loadingSphereID = Overlays.addOverlay("model", { name: "Loading-Sphere", position: Vec3.sum(Vec3.sum(MyAvatar.position, {x: 0.0, y: -1.0, z: 0.0}), Vec3.multiplyQbyV(MyAvatar.orientation, {x: 0, y: 0.95, z: 0})), - orientation: Quat.multiply(Quat.fromVec3Degrees({x: 0, y: 180, z: 0}), MyAvatar.orientation), + orientation: Quat.multiply(Quat.fromVec3Degrees({x: 10, y: 180, z: 0}), MyAvatar.orientation), url: "http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/black-sphere.fbx", dimensions: { x: 20, y: 20, z: 20 }, alpha: 1, visible: isVisible, ignoreRayIntersection: true, drawInFront: true, - grabbable: false + grabbable: false, + parentID: MyAvatar.SELF_ID }); @@ -128,7 +131,7 @@ var loadingBarPlacard = Overlays.addOverlay("image3d", { name: "Loading-Bar-Placard", - localPosition: { x: 0.0 , y: DESTINATION_CARD_Y_OFFSET - 0.99, z: 5.45 }, + localPosition: { x: 0.0 , y: DESTINATION_CARD_Y_OFFSET - 0.99, z: 5.52 }, url: "http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/loadingBar_placard.png", alpha: 1, dimensions: { x: 4, y: 2.8}, @@ -161,6 +164,9 @@ var timerset = false; var lastInterval = Date.now(); var timeElapsed = 0; + var currentDomain = ""; + var timer = null; + var target = 0; function getLeftMargin(overlayID, text) { @@ -171,43 +177,58 @@ } + function resetValues() { + } + + function lerp(a, b, t) { + return ((1 - t) * a + t * b); + } + + function startInterstitialPage() { + if (timer === null) { + print("--------> start page <--------"); + updateOverlays(Window.isPhysicsEnabled()); + target = 0; + currentProgress = 0.1; + timer = Script.setTimeout(update, BASIC_TIMER_INTERVAL_MS); + } + } + function domainChanged(domain) { - var name = AddressManager.placename; - domainName = name.charAt(0).toUpperCase() + name.slice(1); - var domainNameLeftMargin = getLeftMargin(domainNameTextID, domainName); - var textProperties = { - text: domainName, - leftMargin: domainNameLeftMargin - }; + if (domain !== currentDomain) { + print("----------> domain changed <-------------->"); + var name = AddressManager.placename; + domainName = name.charAt(0).toUpperCase() + name.slice(1); + var domainNameLeftMargin = getLeftMargin(domainNameTextID, domainName); + var textProperties = { + text: domainName, + leftMargin: domainNameLeftMargin + }; - var BY = "by "; - var text = BY - var hostLeftMargin = getLeftMargin(domainHostname, text); - var hostnameProperties = { - text: BY, - leftMargin: hostLeftMargin - }; + var BY = "by "; + var text = BY + var hostLeftMargin = getLeftMargin(domainHostname, text); + var hostnameProperties = { + text: BY, + leftMargin: hostLeftMargin + }; - var randomIndex = Math.floor(Math.random() * userTips.length); - var tip = userTips[randomIndex]; - var tipLeftMargin = getLeftMargin(domainToolTip, tip); - var toolTipProperties = { - text: tip, - leftMargin: tipLeftMargin - }; + var randomIndex = Math.floor(Math.random() * userTips.length); + var tip = userTips[randomIndex]; + var tipLeftMargin = getLeftMargin(domainToolTip, tip); + var toolTipProperties = { + text: tip, + leftMargin: tipLeftMargin + }; - var myAvatarDirection = Vec3.UNIT_NEG_Z; - var cardDirectionPrime = {x: 0 , y: 0, z: 5.5}; - var rotationDelta = Quat.rotationBetween(cardDirectionPrime, myAvatarDirection); - var overlayRotation = Quat.multiply(MyAvatar.orientation, rotationDelta); - var mainSphereProperties = { - orientation: overlayRotation - }; + Overlays.editOverlay(domainNameTextID, textProperties); + Overlays.editOverlay(domainHostname, hostnameProperties); + Overlays.editOverlay(domainToolTip, toolTipProperties); - Overlays.editOverlay(loadingSphereID, mainSphereProperties); - Overlays.editOverlay(domainNameTextID, textProperties); - Overlays.editOverlay(domainHostname, hostnameProperties); - Overlays.editOverlay(domainToolTip, toolTipProperties); + + startInterstitialPage(); + currentDomain = domain; + } } var THE_PLACE = "hifi://TheSpot"; @@ -222,26 +243,18 @@ } } - var previousPhysicsStatus = 99999; + var currentProgress = 0.1; function updateOverlays(physicsEnabled) { var properties = { visible: !physicsEnabled }; - var myAvatarDirection = Vec3.UNIT_NEG_Z; - var cardDirectionPrime = {x: 0 , y: 0, z: 5.5}; - var rotationDelta = Quat.rotationBetween(cardDirectionPrime, myAvatarDirection); - var overlayRotation = Quat.multiply(MyAvatar.orientation, rotationDelta); var mainSphereProperties = { - visible: !physicsEnabled, - orientation: overlayRotation + visible: !physicsEnabled }; - if (!HMD.active) { - toolbar.writeProperty("visible", physicsEnabled); - MyAvatar.headOrientation = Quat.multiply(Quat.cancelOutRollAndPitch(MyAvatar.headOrientation), Quat.fromPitchYawRollDegrees(2.5, 0, 0)); - } + Menu.setIsOptionChecked("Show Overlays", physicsEnabled); renderViewTask.getConfig("LightingModel")["enableAmbientLight"] = physicsEnabled; renderViewTask.getConfig("LightingModel")["enableDirectionalLight"] = physicsEnabled; @@ -260,38 +273,46 @@ var thisInterval = Date.now(); var deltaTime = (thisInterval - lastInterval); lastInterval = thisInterval; - if (physicsEnabled !== previousPhysicsStatus) { - if (!physicsEnabled && !timerset) { - updateOverlays(physicsEnabled); - sample = Audio.playSound(tune, { - localOnly: true, - position: MyAvatar.headPosition, - volume: VOLUME - }); - timeElapsed = 0; - timerset = true; - } - previousPhysicsStatus = physicsEnabled; + timeElapsed += deltaTime; + + var nearbyEntitiesReadyCount = Window.getPhysicsNearbyEntitiesReadyCount(); + var stabilityCount = Window.getPhysicsNearbyEntitiesStabilityCount(); + var nearbyEntitiesCount = Window.getPhysicsNearbyEntitiesCount(); + + var stabilityPercentage = (stabilityCount / STABILITY); + if (stabilityPercentage > 1) { + stabilityPercentage = 1; } - if (timerset) { - timeElapsed += deltaTime; - if (timeElapsed >= MAX_ELAPSED_TIME) { - updateOverlays(true); - sample.stop(); - sample = null; - timerset = false; - } + var stabilityProgress = (MAX_X_SIZE * 0.75) * stabilityPercentage; + var entitiesLoadedPercentage = 1; + if (nearbyEntitiesCount > 0) { + entitiesLoadedPercentage = nearbyEntitiesReadyCount / nearbyEntitiesCount; } + var entitiesLoadedProgress = (MAX_X_SIZE * 0.25) * entitiesLoadedPercentage; + var progress = stabilityProgress + entitiesLoadedProgress; + if (progress >= target) { + target = progress; + } + currentProgress = lerp(currentProgress, target, 0.2); + var properties = { + localPosition: { x: -(currentProgress / 2) + 2, y: DESTINATION_CARD_Y_OFFSET - 0.99, z: 5.45 }, + dimensions: { + x: currentProgress, + y: 2.8 + } + }; - Overlays.editOverlay(loadingSphereID, { - position: Vec3.sum(Vec3.sum(MyAvatar.position, {x: 0.0, y: -1.7, z: 0.0}), Vec3.multiplyQbyV(MyAvatar.orientation, {x: 0, y: 0.95, z: 0})) - }); - Script.setTimeout(update, BASIC_TIMER_INTERVAL_MS); + Overlays.editOverlay(loadingBarProgress, properties); + if (physicsEnabled && (currentProgress >= (MAX_X_SIZE - EPSILON))) { + updateOverlays(physicsEnabled); + timer = null; + return; + } + timer = Script.setTimeout(update, BASIC_TIMER_INTERVAL_MS); } - Script.setTimeout(update, BASIC_TIMER_INTERVAL_MS); Overlays.mouseReleaseOnOverlay.connect(clickedOnOverlay); Window.domainChanged.connect(domainChanged); From a9fd034f09ca9e8b8f024d188549f92cd9326f53 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Tue, 7 Aug 2018 16:02:54 -0700 Subject: [PATCH 028/545] switching to location api --- interface/src/Application.cpp | 4 ++-- scripts/system/interstitialPage.js | 26 ++++++++++++-------------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a594756a80..39c24d7562 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1640,7 +1640,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo audioClient->setMuted(!audioClient->isMuted()); } else if (action == controller::toInt(controller::Action::CYCLE_CAMERA)) { cycleCamera(); - } else if (action == controller::toInt(controller::Action::CONTEXT_MENU)) { + } else if (action == controller::toInt(controller::Action::CONTEXT_MENU) && !isInterstitialMode()) { toggleTabletUI(); } else if (action == controller::toInt(controller::Action::RETICLE_X)) { auto oldPos = getApplicationCompositor().getReticlePosition(); @@ -7806,7 +7806,7 @@ float Application::getRenderResolutionScale() const { } void Application::notifyPacketVersionMismatch() { - if (!_notifiedPacketVersionMismatchThisDomain) { + if (!_notifiedPacketVersionMismatchThisDomain && !isInterstitialMode()) { _notifiedPacketVersionMismatchThisDomain = true; QString message = "The location you are visiting is running an incompatible server version.\n"; diff --git a/scripts/system/interstitialPage.js b/scripts/system/interstitialPage.js index 6960272e11..b18d88d796 100644 --- a/scripts/system/interstitialPage.js +++ b/scripts/system/interstitialPage.js @@ -186,7 +186,6 @@ function startInterstitialPage() { if (timer === null) { - print("--------> start page <--------"); updateOverlays(Window.isPhysicsEnabled()); target = 0; currentProgress = 0.1; @@ -195,8 +194,9 @@ } function domainChanged(domain) { + print("domain changed: " + domain); if (domain !== currentDomain) { - print("----------> domain changed <-------------->"); + MyAvatar.restoreAnimation(); var name = AddressManager.placename; domainName = name.charAt(0).toUpperCase() + name.slice(1); var domainNameLeftMargin = getLeftMargin(domainNameTextID, domainName); @@ -205,13 +205,11 @@ leftMargin: domainNameLeftMargin }; - var BY = "by "; - var text = BY - var hostLeftMargin = getLeftMargin(domainHostname, text); + /*var hostLeftMargin = getLeftMargin(domainHostname, text); var hostnameProperties = { text: BY, leftMargin: hostLeftMargin - }; + };*/ var randomIndex = Math.floor(Math.random() * userTips.length); var tip = userTips[randomIndex]; @@ -222,7 +220,7 @@ }; Overlays.editOverlay(domainNameTextID, textProperties); - Overlays.editOverlay(domainHostname, hostnameProperties); + // Overlays.editOverlay(domainHostname, hostnameProperties); Overlays.editOverlay(domainToolTip, toolTipProperties); @@ -234,12 +232,9 @@ var THE_PLACE = "hifi://TheSpot"; function clickedOnOverlay(overlayID, event) { print(overlayID + " other: " + loadingToTheSpotID); - print(event.button === "Primary"); if (loadingToTheSpotID === overlayID) { - if (timerset) { - timeElapsed = 0; - } - AddressManager.handleLookupString(THE_PLACE); + print("-------> heading to theb spot <--------"); + location.handleLookupString(THE_PLACE); } } @@ -254,7 +249,7 @@ visible: !physicsEnabled }; - Menu.setIsOptionChecked("Show Overlays", physicsEnabled); + // Menu.setIsOptionChecked("Show Overlays", physicsEnabled); renderViewTask.getConfig("LightingModel")["enableAmbientLight"] = physicsEnabled; renderViewTask.getConfig("LightingModel")["enableDirectionalLight"] = physicsEnabled; @@ -314,7 +309,10 @@ } Overlays.mouseReleaseOnOverlay.connect(clickedOnOverlay); - Window.domainChanged.connect(domainChanged); + location.hostChanged.connect(domainChanged); + location.lookupResultsFinished.connect(function() { + print("connected: " + location.isConnected()); + }); function cleanup() { Overlays.deleteOverlay(loadingSphereID); From c774dd7f5bf0734b771fc0616a3fff47cfa9081e Mon Sep 17 00:00:00 2001 From: amantley Date: Wed, 8 Aug 2018 17:52:22 -0700 Subject: [PATCH 029/545] debugging to solve the no-neck crazy scale problem --- interface/src/Application.cpp | 5 +++++ interface/src/avatar/MyAvatar.cpp | 2 ++ interface/src/avatar/MySkeletonModel.cpp | 5 +++++ .../src/avatars-renderer/Avatar.cpp | 3 +++ .../src/avatars-renderer/SkeletonModel.cpp | 19 +++++++++++++++++++ libraries/shared/src/shared/Camera.cpp | 1 + 6 files changed, 35 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0bbd2b1c17..8a7a5c610a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3064,6 +3064,7 @@ void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) { auto myAvatar = getMyAvatar(); boomOffset = myAvatar->getModelScale() * myAvatar->getBoomLength() * -IDENTITY_FORWARD; + //qCDebug(interfaceapp) << "boom offset" << boomOffset; // The render mode is default or mirror if the camera is in mirror mode, assigned further below renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; @@ -3074,10 +3075,12 @@ void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) { _thirdPersonHMDCameraBoomValid= false; if (isHMDMode()) { mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); + //qCDebug(interfaceapp) << "camera 1rst translation hmd " << extractTranslation(camMat); _myCamera.setPosition(extractTranslation(camMat)); _myCamera.setOrientation(glmExtractRotation(camMat)); } else { + //qCDebug(interfaceapp) << "camera 1rst translation desktop " << myAvatar->getDefaultEyePosition(); _myCamera.setPosition(myAvatar->getDefaultEyePosition()); _myCamera.setOrientation(myAvatar->getMyHead()->getHeadOrientation()); } @@ -3099,6 +3102,7 @@ void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) { _myCamera.setOrientation(glm::normalize(glmExtractRotation(worldCameraMat))); _myCamera.setPosition(extractTranslation(worldCameraMat)); + //qCDebug(interfaceapp) << "camera translation 3rd hmd " << extractTranslation(worldCameraMat); } else { _thirdPersonHMDCameraBoomValid = false; @@ -3112,6 +3116,7 @@ void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) { _myCamera.setPosition(myAvatar->getDefaultEyePosition() + myAvatar->getWorldOrientation() * boomOffset); } + qCDebug(interfaceapp) << "camera translation 3rd desktop " << (myAvatar->getDefaultEyePosition() + _myCamera.getOrientation() * boomOffset); } } else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 3f738ea4cb..9971f90bd6 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1704,8 +1704,10 @@ glm::vec3 MyAvatar::getSkeletonPosition() const { // The avatar is rotated PI about the yAxis, so we have to correct for it // to get the skeleton offset contribution in the world-frame. const glm::quat FLIP = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f)); + //qCDebug(interfaceapp) << "position third person " << getWorldPosition(); return getWorldPosition() + getWorldOrientation() * FLIP * _skeletonOffset; } + //qCDebug(interfaceapp) << "position first person " << Avatar::getWorldPosition(); return Avatar::getWorldPosition(); } diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 0fc5e7521e..86085798ab 100644 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -95,7 +95,9 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { // make sure lookAt is not too close to face (avoid crosseyes) glm::vec3 lookAt = head->getLookAtPosition(); + //qCDebug(interfaceapp) << "look at " << lookAt; glm::vec3 focusOffset = lookAt - _owningAvatar->getHead()->getEyePosition(); + //qCDebug(interfaceapp) << "focus offset " << focusOffset; float focusDistance = glm::length(focusOffset); const float MIN_LOOK_AT_FOCUS_DISTANCE = 1.0f; if (focusDistance < MIN_LOOK_AT_FOCUS_DISTANCE && focusDistance > EPSILON) { @@ -113,6 +115,8 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { glm::mat4 avatarToWorldMatrix = createMatFromQuatAndPos(myAvatar->getWorldOrientation(), myAvatar->getWorldPosition()); glm::mat4 sensorToWorldMatrix = myAvatar->getSensorToWorldMatrix(); params.rigToSensorMatrix = glm::inverse(sensorToWorldMatrix) * avatarToWorldMatrix * rigToAvatarMatrix; + //qCDebug(interfaceapp) << "AVATAR: " << avatarToWorldMatrix; + //qCDebug(interfaceapp) << "SENSOR " << sensorToWorldMatrix; // input action is the highest priority source for head orientation. auto avatarHeadPose = myAvatar->getControllerPoseInAvatarFrame(controller::Action::HEAD); @@ -282,6 +286,7 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { eyeParams.leftEyeJointIndex = geometry.leftEyeJointIndex; eyeParams.rightEyeJointIndex = geometry.rightEyeJointIndex; + //qCDebug(interfaceapp) << "right eye index is " << geometry.leftEyeJointIndex; _rig.updateFromEyeParameters(eyeParams); updateFingers(); diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index 69356cdfaa..07d1edcabb 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -169,6 +169,8 @@ AABox Avatar::getBounds() const { // approximately 2m tall, scaled to user request. return AABox(getWorldPosition() - glm::vec3(getModelScale()), getModelScale() * 2.0f); } + //float temp = _skeletonModel->getRenderableMeshBound().getLargestDimension(); + //qCDebug(animation) << " largest bounding box dimension " << temp; return _skeletonModel->getRenderableMeshBound(); } @@ -1775,6 +1777,7 @@ void Avatar::buildUnscaledEyeHeightCache() { // Sanity check by looking at the model extents. Extents meshExtents = _skeletonModel->getUnscaledMeshExtents(); float meshHeight = meshExtents.size().y; + //qCDebug(animation) << "mesh height " << meshHeight << " skeleton height " << skeletonHeight; // if we determine the mesh is much larger then the skeleton, then we use the mesh height instead. // This helps prevent absurdly large avatars from exceeding the domain height limit. diff --git a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp index de8c02f10e..83caaede8d 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp @@ -71,14 +71,23 @@ void SkeletonModel::initJointStates() { qCWarning(avatars_renderer) << "Bad head joint! Got:" << headJointIndex << "jointCount:" << _rig.getJointStateCount(); } glm::vec3 leftEyePosition, rightEyePosition; + qCDebug(avatars_renderer) << "initial left and right eyes " << leftEyePosition << " " << rightEyePosition; getEyeModelPositions(leftEyePosition, rightEyePosition); + qCDebug(avatars_renderer) << "after setting the left and right eyes " << leftEyePosition << " " << rightEyePosition; glm::vec3 midEyePosition = (leftEyePosition + rightEyePosition) / 2.0f; int rootJointIndex = geometry.rootJointIndex; glm::vec3 rootModelPosition; getJointPosition(rootJointIndex, rootModelPosition); + qCDebug(avatars_renderer) << "root joint index " << rootJointIndex << " root position: " << rootModelPosition; _defaultEyeModelPosition = midEyePosition - rootModelPosition; + if (headJointIndex > -1) { + glm::vec3 headModelPosition; + getJointPosition(headJointIndex, headModelPosition); + qCDebug(avatars_renderer) << "we have a head joint " << headJointIndex << " and " << headModelPosition; + } + qCDebug(avatars_renderer) << "the default eye pos " << _defaultEyeModelPosition << " and scale " << _scale; // Skeleton may have already been scaled so unscale it _defaultEyeModelPosition = _defaultEyeModelPosition / _scale; @@ -294,6 +303,16 @@ bool SkeletonModel::getEyeModelPositions(glm::vec3& firstEyePosition, glm::vec3& firstEyePosition = baseEyePosition + headRotation * glm::vec3(EYE_SEPARATION, 0.0f, EYES_FORWARD) * headHeight; secondEyePosition = baseEyePosition + headRotation * glm::vec3(-EYE_SEPARATION, 0.0f, EYES_FORWARD) * headHeight; return true; + } else if (getJointPosition(geometry.headJointIndex, headPosition)) { + glm::vec3 baseEyePosition = headPosition; + glm::quat headRotation; + getJointRotation(geometry.headJointIndex, headRotation); + const float EYES_FORWARD = 0.25f; + const float EYE_SEPARATION = 0.1f; + float headHeight = glm::distance(neckPosition, headPosition); + firstEyePosition = baseEyePosition + headRotation * glm::vec3(EYE_SEPARATION, 0.0f, EYES_FORWARD); + secondEyePosition = baseEyePosition + headRotation * glm::vec3(-EYE_SEPARATION, 0.0f, EYES_FORWARD); + return true; } return false; } diff --git a/libraries/shared/src/shared/Camera.cpp b/libraries/shared/src/shared/Camera.cpp index 787b7bfb1a..c80e14d87c 100644 --- a/libraries/shared/src/shared/Camera.cpp +++ b/libraries/shared/src/shared/Camera.cpp @@ -9,6 +9,7 @@ // #include "Camera.h" +//#include "../SharedLogging.h" /**jsdoc *

Camera modes affect the position of the camera and the controls for camera movement. The camera can be in one of the From 0fed48bd0e7b8ce0411dc25f5944ed2d1a3d0d3d Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Wed, 8 Aug 2018 18:15:27 -0700 Subject: [PATCH 030/545] improving interstitial page --- scripts/system/interstitialPage.js | 199 ++++++++++++++++++++++++----- 1 file changed, 164 insertions(+), 35 deletions(-) diff --git a/scripts/system/interstitialPage.js b/scripts/system/interstitialPage.js index b18d88d796..76900bd77c 100644 --- a/scripts/system/interstitialPage.js +++ b/scripts/system/interstitialPage.js @@ -10,25 +10,30 @@ // /* global Script, Controller, Overlays, Quat, MyAvatar, Entities, print, Vec3, AddressManager, Render, Window, Toolbars, - Camera, HMD*/ + Camera, HMD, location, Account*/ (function() { + Script.include("/~/system/libraries/Xform.js"); + var DEBUG = true; var MAX_X_SIZE = 5; var EPSILON = 0.25; var isVisible = false; var STABILITY = 3.0; - var defaultOffset = -0.5; var VOLUME = 0.4; var tune = SoundCache.getSound("http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/crystals_and_voices.wav"); var sample = null; var MAX_LEFT_MARGIN = 1.9; var INNER_CIRCLE_WIDTH = 4.7; var DESTINATION_CARD_Y_OFFSET = 2; - var SYSTEM_TOOL_BAR = "com.highfidelity.interface.toolbar.system"; - var MAX_ELAPSED_TIME = 5 * 1000; // time in ms + var DEFAULT_Z_OFFSET = 5.45; - var toolbar = Toolbars.getToolbar(SYSTEM_TOOL_BAR); var renderViewTask = Render.getConfig("RenderMainView"); + var request = Script.require('request').request; + var BUTTON_PROPERTIES = { + text: "Interstitial" + }; + var tablet = null; + var button = null; // Tips have a character limit of 69 var userTips = [ @@ -49,12 +54,14 @@ "Tip: Log in to make friends, visit new domains, and save avatars!" ]; + var DEFAULT_DIMENSIONS = { x: 20, y: 20, z: 20 }; + var loadingSphereID = Overlays.addOverlay("model", { name: "Loading-Sphere", position: Vec3.sum(Vec3.sum(MyAvatar.position, {x: 0.0, y: -1.0, z: 0.0}), Vec3.multiplyQbyV(MyAvatar.orientation, {x: 0, y: 0.95, z: 0})), - orientation: Quat.multiply(Quat.fromVec3Degrees({x: 10, y: 180, z: 0}), MyAvatar.orientation), + orientation: Quat.multiply(Quat.fromVec3Degrees({x: 0, y: 180, z: 0}), MyAvatar.orientation), url: "http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/black-sphere.fbx", - dimensions: { x: 20, y: 20, z: 20 }, + dimensions: DEFAULT_DIMENSIONS, alpha: 1, visible: isVisible, ignoreRayIntersection: true, @@ -63,11 +70,23 @@ parentID: MyAvatar.SELF_ID }); + var anchorOverlay = Overlays.addOverlay("cube", { + dimensions: {x: 0.2, y: 0.2, z: 0.2}, + visible: true, + grabbable: false, + ignoreRayIntersection: true, + localPosition: {x: 0.0, y: getAnchorLocalYOffset(), z: DEFAULT_Z_OFFSET }, + orientation: Quat.multiply(Quat.fromVec3Degrees({x: 0, y: 180, z: 0}), MyAvatar.orientation), + solid: true, + drawInFront: true, + parentID: MyAvatar.SELF_ID + }); - var domainName = ""; + + var domainName = "Test"; var domainNameTextID = Overlays.addOverlay("text3d", { name: "Loading-Destination-Card-Text", - localPosition: { x: 0.0, y: DESTINATION_CARD_Y_OFFSET + 0.8, z: 5.45 }, + localPosition: { x: 0.0, y: 0.8, z: 0.0 }, text: domainName, textAlpha: 1, backgroundAlpha: 0, @@ -77,15 +96,15 @@ drawInFront: true, grabbable: false, localOrientation: Quat.fromVec3Degrees({ x: 0, y: 180, z: 0 }), - parentID: loadingSphereID + parentID: anchorOverlay }); - var hostName = ""; + var domainText = ""; - var domainHostname = Overlays.addOverlay("text3d", { + var domainDescription = Overlays.addOverlay("text3d", { name: "Loading-Hostname", - localPosition: { x: 0.0, y: DESTINATION_CARD_Y_OFFSET + 0.32, z: 5.45 }, - text: hostName, + localPosition: { x: 0.0, y: 0.32, z: 0.0 }, + text: domainText, textAlpha: 1, backgroundAlpha: 0, lineHeight: 0.13, @@ -94,14 +113,14 @@ drawInFront: true, grabbable: false, localOrientation: Quat.fromVec3Degrees({ x: 0, y: 180, z: 0 }), - parentID: loadingSphereID + parentID: anchorOverlay }); var toolTip = ""; var domainToolTip = Overlays.addOverlay("text3d", { name: "Loading-Tooltip", - localPosition: { x: 0.0 , y: DESTINATION_CARD_Y_OFFSET - 1.6, z: 5.45 }, + localPosition: { x: 0.0 , y: -1.6, z: 0.0 }, text: toolTip, textAlpha: 1, backgroundAlpha: 0, @@ -111,12 +130,12 @@ drawInFront: true, grabbable: false, localOrientation: Quat.fromVec3Degrees({ x: 0, y: 180, z: 0 }), - parentID: loadingSphereID + parentID: anchorOverlay }); var loadingToTheSpotID = Overlays.addOverlay("image3d", { name: "Loading-Destination-Card-Text", - localPosition: { x: 0.0 , y: DESTINATION_CARD_Y_OFFSET - 1.8, z: 5.45 }, + localPosition: { x: 0.0 , y: -1.8, z: 0.0 }, url: "http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/goTo_button.png", alpha: 1, dimensions: { x: 1.2, y: 0.6}, @@ -126,12 +145,12 @@ drawInFront: true, grabbable: false, localOrientation: Quat.fromVec3Degrees({ x: 0.0, y: 180.0, z: 0.0 }), - parentID: loadingSphereID + parentID: anchorOverlay }); var loadingBarPlacard = Overlays.addOverlay("image3d", { name: "Loading-Bar-Placard", - localPosition: { x: 0.0 , y: DESTINATION_CARD_Y_OFFSET - 0.99, z: 5.52 }, + localPosition: { x: 0.0 , y: -0.99, z: 0.07 }, url: "http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/loadingBar_placard.png", alpha: 1, dimensions: { x: 4, y: 2.8}, @@ -141,12 +160,12 @@ drawInFront: true, grabbable: false, localOrientation: Quat.fromVec3Degrees({ x: 0.0, y: 180.0, z: 0.0 }), - parentID: loadingSphereID + parentID: anchorOverlay }); var loadingBarProgress = Overlays.addOverlay("image3d", { name: "Loading-Bar-Progress", - localPosition: { x: 0.0 , y: DESTINATION_CARD_Y_OFFSET - 0.99, z: 5.45 }, + localPosition: { x: 0.0 , y: -0.99, z: 0.0 }, url: "http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/loadingBar_progress.png", alpha: 1, dimensions: { x: 4, y: 2.8}, @@ -156,7 +175,7 @@ drawInFront: true, grabbable: false, localOrientation: Quat.fromVec3Degrees({ x: 0.0, y: 180.0, z: 0.0 }), - parentID: loadingSphereID + parentID: anchorOverlay }); var TARGET_UPDATE_HZ = 60; // 50hz good enough, but we're using update @@ -169,6 +188,16 @@ var target = 0; + function getAnchorLocalYOffset() { + var loadingSpherePosition = Overlays.getProperty(loadingSphereID, "position"); + var loadingSphereOrientation = Overlays.getProperty(loadingSphereID, "rotation"); + var overlayXform = new Xform(loadingSphereOrientation, loadingSpherePosition); + var worldToOverlayXform = overlayXform.inv(); + var headPosition = MyAvatar.getHeadPosition(); + var headPositionInOverlaySpace = worldToOverlayXform.xformPoint(headPosition); + return headPositionInOverlaySpace.y; + } + function getLeftMargin(overlayID, text) { var textSize = Overlays.textSize(overlayID, text); var sizeDifference = ((INNER_CIRCLE_WIDTH - textSize.width) / 2); @@ -176,7 +205,6 @@ return leftMargin; } - function resetValues() { } @@ -186,13 +214,28 @@ function startInterstitialPage() { if (timer === null) { + print("----------> starting <----------"); updateOverlays(Window.isPhysicsEnabled()); + startAudio(); target = 0; currentProgress = 0.1; timer = Script.setTimeout(update, BASIC_TIMER_INTERVAL_MS); } } + function startAudio() { + sample = Audio.playSound(tune, { + localOnly: true, + position: MyAvatar.getHeadPosition(), + volume: VOLUME + }); + } + + function endAudio() { + sample.stop(); + sample = null; + } + function domainChanged(domain) { print("domain changed: " + domain); if (domain !== currentDomain) { @@ -205,11 +248,23 @@ leftMargin: domainNameLeftMargin }; - /*var hostLeftMargin = getLeftMargin(domainHostname, text); - var hostnameProperties = { - text: BY, - leftMargin: hostLeftMargin - };*/ + var url = Account.metaverseServerURL + '/api/v1/places/' + domain; + request({ + uri: url + }, function(error, data) { + if (data.status === "success") { + print("-----------> settings domain description <----------"); + var domainInfo = data.data; + var domainDescriptionText = domainInfo.place.description; + print("domainText: " + domainDescriptionText); + var leftMargin = getLeftMargin(domainDescription, domainDescriptionText); + var domainDescriptionProperties = { + text: domainDescriptionText, + leftMargin: leftMargin + }; + Overlays.editOverlay(domainDescription, domainDescriptionProperties); + } + }); var randomIndex = Math.floor(Math.random() * userTips.length); var tip = userTips[randomIndex]; @@ -220,7 +275,6 @@ }; Overlays.editOverlay(domainNameTextID, textProperties); - // Overlays.editOverlay(domainHostname, hostnameProperties); Overlays.editOverlay(domainToolTip, toolTipProperties); @@ -233,7 +287,6 @@ function clickedOnOverlay(overlayID, event) { print(overlayID + " other: " + loadingToTheSpotID); if (loadingToTheSpotID === overlayID) { - print("-------> heading to theb spot <--------"); location.handleLookupString(THE_PLACE); } } @@ -249,18 +302,70 @@ visible: !physicsEnabled }; + var domainTextProperties = { + text: domainText, + visible: !physicsEnabled + }; + // Menu.setIsOptionChecked("Show Overlays", physicsEnabled); + if (!HMD.active) { + MyAvatar.headOrientation = Quat.multiply(Quat.cancelOutRollAndPitch(MyAvatar.headOrientation), Quat.fromPitchYawRollDegrees(-3.0, 0, 0)); + } + renderViewTask.getConfig("LightingModel")["enableAmbientLight"] = physicsEnabled; renderViewTask.getConfig("LightingModel")["enableDirectionalLight"] = physicsEnabled; renderViewTask.getConfig("LightingModel")["enablePointLight"] = physicsEnabled; Overlays.editOverlay(loadingSphereID, mainSphereProperties); Overlays.editOverlay(loadingToTheSpotID, properties); Overlays.editOverlay(domainNameTextID, properties); - Overlays.editOverlay(domainHostname, properties); + Overlays.editOverlay(domainDescription, domainTextProperties); Overlays.editOverlay(domainToolTip, properties); Overlays.editOverlay(loadingBarPlacard, properties); Overlays.editOverlay(loadingBarProgress, properties); + + Camera.mode = "first person"; + } + + + function scaleInterstitialPage(sensorToWorldScale) { + var yOffset = getAnchorLocalYOffset(); + var localPosition = { + x: 0.0, + y: yOffset, + z: 5.45 + }; + + Overlays.editOverlay(anchorOverlay, { localPosition: localPosition }); + } + + var progress = 0; + function updateProgress() { + print("updateProgress"); + var thisInterval = Date.now(); + var deltaTime = (thisInterval - lastInterval); + lastInterval = thisInterval; + timeElapsed += deltaTime; + + progress += MAX_X_SIZE * (deltaTime / 1000); + print(progress); + var properties = { + localPosition: { x: -(progress / 1.98) + 2, y: -0.99, z: 0.0 }, + dimensions: { + x: progress, + y: 2.8 + } + }; + + if (progress > MAX_X_SIZE) { + progress = 0; + } + + Overlays.editOverlay(loadingBarProgress, properties); + + if (!toggle) { + Script.setTimeout(updateProgress, BASIC_TIMER_INTERVAL_MS); + } } function update() { @@ -292,7 +397,7 @@ } currentProgress = lerp(currentProgress, target, 0.2); var properties = { - localPosition: { x: -(currentProgress / 2) + 2, y: DESTINATION_CARD_Y_OFFSET - 0.99, z: 5.45 }, + localPosition: { x: -(currentProgress / 2) + 2, y: 0.99, z: 5.45 }, dimensions: { x: currentProgress, y: 2.8 @@ -301,7 +406,9 @@ Overlays.editOverlay(loadingBarProgress, properties); if (physicsEnabled && (currentProgress >= (MAX_X_SIZE - EPSILON))) { + print("----------> ending <--------"); updateOverlays(physicsEnabled); + endAudio(); timer = null; return; } @@ -311,17 +418,39 @@ Overlays.mouseReleaseOnOverlay.connect(clickedOnOverlay); location.hostChanged.connect(domainChanged); location.lookupResultsFinished.connect(function() { - print("connected: " + location.isConnected()); + print("connected: " + location.isConnected); }); + MyAvatar.sensorToWorldScaleChanged.connect(scaleInterstitialPage); + + var toggle = true; + if (DEBUG) { + tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); + button = tablet.addButton(BUTTON_PROPERTIES); + + button.clicked.connect(function() { + toggle = !toggle; + updateOverlays(toggle); + + if (!toggle) { + Script.setTimeout(updateProgress, BASIC_TIMER_INTERVAL_MS); + } + }); + } + function cleanup() { Overlays.deleteOverlay(loadingSphereID); Overlays.deleteOverlay(loadingToTheSpotID); Overlays.deleteOverlay(domainNameTextID); - Overlays.deleteOverlay(domainHostname); + Overlays.deleteOverlay(domainDescription); Overlays.deleteOverlay(domainToolTip); Overlays.deleteOverlay(loadingBarPlacard); Overlays.deleteOverlay(loadingBarProgress); + Overlays.deleteOverlay(anchorOverlay); + + if (DEBUG) { + tablet.removeButton(button); + } } Script.scriptEnding.connect(cleanup); From a3f2fd1f235b014fd672e3b2f61a153103b84312 Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 9 Aug 2018 11:33:27 -0700 Subject: [PATCH 031/545] removed some print statements and added the code to use the head parent when the neck is missing, this allows for cauterization --- interface/src/Application.cpp | 5 ----- interface/src/avatar/MyAvatar.cpp | 8 +++++--- interface/src/avatar/MySkeletonModel.cpp | 5 ----- .../avatars-renderer/src/avatars-renderer/Avatar.cpp | 3 --- libraries/render-utils/src/CauterizedModel.cpp | 2 ++ libraries/shared/src/shared/Camera.cpp | 1 - 6 files changed, 7 insertions(+), 17 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 8a7a5c610a..0bbd2b1c17 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3064,7 +3064,6 @@ void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) { auto myAvatar = getMyAvatar(); boomOffset = myAvatar->getModelScale() * myAvatar->getBoomLength() * -IDENTITY_FORWARD; - //qCDebug(interfaceapp) << "boom offset" << boomOffset; // The render mode is default or mirror if the camera is in mirror mode, assigned further below renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; @@ -3075,12 +3074,10 @@ void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) { _thirdPersonHMDCameraBoomValid= false; if (isHMDMode()) { mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); - //qCDebug(interfaceapp) << "camera 1rst translation hmd " << extractTranslation(camMat); _myCamera.setPosition(extractTranslation(camMat)); _myCamera.setOrientation(glmExtractRotation(camMat)); } else { - //qCDebug(interfaceapp) << "camera 1rst translation desktop " << myAvatar->getDefaultEyePosition(); _myCamera.setPosition(myAvatar->getDefaultEyePosition()); _myCamera.setOrientation(myAvatar->getMyHead()->getHeadOrientation()); } @@ -3102,7 +3099,6 @@ void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) { _myCamera.setOrientation(glm::normalize(glmExtractRotation(worldCameraMat))); _myCamera.setPosition(extractTranslation(worldCameraMat)); - //qCDebug(interfaceapp) << "camera translation 3rd hmd " << extractTranslation(worldCameraMat); } else { _thirdPersonHMDCameraBoomValid = false; @@ -3116,7 +3112,6 @@ void Application::updateCamera(RenderArgs& renderArgs, float deltaTime) { _myCamera.setPosition(myAvatar->getDefaultEyePosition() + myAvatar->getWorldOrientation() * boomOffset); } - qCDebug(interfaceapp) << "camera translation 3rd desktop " << (myAvatar->getDefaultEyePosition() + _myCamera.getOrientation() * boomOffset); } } else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 9971f90bd6..8ba0841196 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1704,10 +1704,8 @@ glm::vec3 MyAvatar::getSkeletonPosition() const { // The avatar is rotated PI about the yAxis, so we have to correct for it // to get the skeleton offset contribution in the world-frame. const glm::quat FLIP = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f)); - //qCDebug(interfaceapp) << "position third person " << getWorldPosition(); return getWorldPosition() + getWorldOrientation() * FLIP * _skeletonOffset; } - //qCDebug(interfaceapp) << "position first person " << Avatar::getWorldPosition(); return Avatar::getWorldPosition(); } @@ -1992,7 +1990,11 @@ void MyAvatar::initHeadBones() { neckJointIndex = _skeletonModel->getFBXGeometry().neckJointIndex; } if (neckJointIndex == -1) { - return; + neckJointIndex = (_skeletonModel->getFBXGeometry().headJointIndex - 1); + if (neckJointIndex < 0) { + //return if the head is not even there. can't cauterize!! + return; + } } _headBoneSet.clear(); std::queue q; diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 86085798ab..0fc5e7521e 100644 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -95,9 +95,7 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { // make sure lookAt is not too close to face (avoid crosseyes) glm::vec3 lookAt = head->getLookAtPosition(); - //qCDebug(interfaceapp) << "look at " << lookAt; glm::vec3 focusOffset = lookAt - _owningAvatar->getHead()->getEyePosition(); - //qCDebug(interfaceapp) << "focus offset " << focusOffset; float focusDistance = glm::length(focusOffset); const float MIN_LOOK_AT_FOCUS_DISTANCE = 1.0f; if (focusDistance < MIN_LOOK_AT_FOCUS_DISTANCE && focusDistance > EPSILON) { @@ -115,8 +113,6 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { glm::mat4 avatarToWorldMatrix = createMatFromQuatAndPos(myAvatar->getWorldOrientation(), myAvatar->getWorldPosition()); glm::mat4 sensorToWorldMatrix = myAvatar->getSensorToWorldMatrix(); params.rigToSensorMatrix = glm::inverse(sensorToWorldMatrix) * avatarToWorldMatrix * rigToAvatarMatrix; - //qCDebug(interfaceapp) << "AVATAR: " << avatarToWorldMatrix; - //qCDebug(interfaceapp) << "SENSOR " << sensorToWorldMatrix; // input action is the highest priority source for head orientation. auto avatarHeadPose = myAvatar->getControllerPoseInAvatarFrame(controller::Action::HEAD); @@ -286,7 +282,6 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { eyeParams.leftEyeJointIndex = geometry.leftEyeJointIndex; eyeParams.rightEyeJointIndex = geometry.rightEyeJointIndex; - //qCDebug(interfaceapp) << "right eye index is " << geometry.leftEyeJointIndex; _rig.updateFromEyeParameters(eyeParams); updateFingers(); diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index 07d1edcabb..69356cdfaa 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -169,8 +169,6 @@ AABox Avatar::getBounds() const { // approximately 2m tall, scaled to user request. return AABox(getWorldPosition() - glm::vec3(getModelScale()), getModelScale() * 2.0f); } - //float temp = _skeletonModel->getRenderableMeshBound().getLargestDimension(); - //qCDebug(animation) << " largest bounding box dimension " << temp; return _skeletonModel->getRenderableMeshBound(); } @@ -1777,7 +1775,6 @@ void Avatar::buildUnscaledEyeHeightCache() { // Sanity check by looking at the model extents. Extents meshExtents = _skeletonModel->getUnscaledMeshExtents(); float meshHeight = meshExtents.size().y; - //qCDebug(animation) << "mesh height " << meshHeight << " skeleton height " << skeletonHeight; // if we determine the mesh is much larger then the skeleton, then we use the mesh height instead. // This helps prevent absurdly large avatars from exceeding the domain height limit. diff --git a/libraries/render-utils/src/CauterizedModel.cpp b/libraries/render-utils/src/CauterizedModel.cpp index 80a9c5ccae..b5b8c039a1 100644 --- a/libraries/render-utils/src/CauterizedModel.cpp +++ b/libraries/render-utils/src/CauterizedModel.cpp @@ -139,6 +139,8 @@ void CauterizedModel::updateClusterMatrices() { glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)); auto cauterizeMatrix = _rig.getJointTransform(geometry.neckJointIndex) * zeroScale; + // qCDebug(renderutils) << "cauterize matrix: " << cauterizeMatrix; + for (int i = 0; i < _cauterizeMeshStates.size(); i++) { Model::MeshState& state = _cauterizeMeshStates[i]; const FBXMesh& mesh = geometry.meshes.at(i); diff --git a/libraries/shared/src/shared/Camera.cpp b/libraries/shared/src/shared/Camera.cpp index c80e14d87c..787b7bfb1a 100644 --- a/libraries/shared/src/shared/Camera.cpp +++ b/libraries/shared/src/shared/Camera.cpp @@ -9,7 +9,6 @@ // #include "Camera.h" -//#include "../SharedLogging.h" /**jsdoc *

Camera modes affect the position of the camera and the controls for camera movement. The camera can be in one of the From f26d6b8c3dc30957477271987647e4f60c96a708 Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 9 Aug 2018 12:15:35 -0700 Subject: [PATCH 032/545] cleaned up code and changed the forward offset for the default eyes when there is no neck bone --- interface/src/avatar/MyAvatar.cpp | 2 +- .../src/avatars-renderer/SkeletonModel.cpp | 15 +++------------ libraries/render-utils/src/CauterizedModel.cpp | 2 -- 3 files changed, 4 insertions(+), 15 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 8ba0841196..d456028bbe 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1992,7 +1992,7 @@ void MyAvatar::initHeadBones() { if (neckJointIndex == -1) { neckJointIndex = (_skeletonModel->getFBXGeometry().headJointIndex - 1); if (neckJointIndex < 0) { - //return if the head is not even there. can't cauterize!! + // return if the head is not even there. can't cauterize!! return; } } diff --git a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp index 83caaede8d..11bad6c1b8 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp @@ -71,23 +71,14 @@ void SkeletonModel::initJointStates() { qCWarning(avatars_renderer) << "Bad head joint! Got:" << headJointIndex << "jointCount:" << _rig.getJointStateCount(); } glm::vec3 leftEyePosition, rightEyePosition; - qCDebug(avatars_renderer) << "initial left and right eyes " << leftEyePosition << " " << rightEyePosition; getEyeModelPositions(leftEyePosition, rightEyePosition); - qCDebug(avatars_renderer) << "after setting the left and right eyes " << leftEyePosition << " " << rightEyePosition; glm::vec3 midEyePosition = (leftEyePosition + rightEyePosition) / 2.0f; int rootJointIndex = geometry.rootJointIndex; glm::vec3 rootModelPosition; getJointPosition(rootJointIndex, rootModelPosition); - qCDebug(avatars_renderer) << "root joint index " << rootJointIndex << " root position: " << rootModelPosition; _defaultEyeModelPosition = midEyePosition - rootModelPosition; - if (headJointIndex > -1) { - glm::vec3 headModelPosition; - getJointPosition(headJointIndex, headModelPosition); - qCDebug(avatars_renderer) << "we have a head joint " << headJointIndex << " and " << headModelPosition; - } - qCDebug(avatars_renderer) << "the default eye pos " << _defaultEyeModelPosition << " and scale " << _scale; // Skeleton may have already been scaled so unscale it _defaultEyeModelPosition = _defaultEyeModelPosition / _scale; @@ -307,11 +298,11 @@ bool SkeletonModel::getEyeModelPositions(glm::vec3& firstEyePosition, glm::vec3& glm::vec3 baseEyePosition = headPosition; glm::quat headRotation; getJointRotation(geometry.headJointIndex, headRotation); - const float EYES_FORWARD = 0.25f; + const float EYES_FORWARD_HEAD_ONLY = 0.30f; const float EYE_SEPARATION = 0.1f; float headHeight = glm::distance(neckPosition, headPosition); - firstEyePosition = baseEyePosition + headRotation * glm::vec3(EYE_SEPARATION, 0.0f, EYES_FORWARD); - secondEyePosition = baseEyePosition + headRotation * glm::vec3(-EYE_SEPARATION, 0.0f, EYES_FORWARD); + firstEyePosition = baseEyePosition + headRotation * glm::vec3(EYE_SEPARATION, 0.0f, EYES_FORWARD_HEAD_ONLY); + secondEyePosition = baseEyePosition + headRotation * glm::vec3(-EYE_SEPARATION, 0.0f, EYES_FORWARD_HEAD_ONLY); return true; } return false; diff --git a/libraries/render-utils/src/CauterizedModel.cpp b/libraries/render-utils/src/CauterizedModel.cpp index b5b8c039a1..80a9c5ccae 100644 --- a/libraries/render-utils/src/CauterizedModel.cpp +++ b/libraries/render-utils/src/CauterizedModel.cpp @@ -139,8 +139,6 @@ void CauterizedModel::updateClusterMatrices() { glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)); auto cauterizeMatrix = _rig.getJointTransform(geometry.neckJointIndex) * zeroScale; - // qCDebug(renderutils) << "cauterize matrix: " << cauterizeMatrix; - for (int i = 0; i < _cauterizeMeshStates.size(); i++) { Model::MeshState& state = _cauterizeMeshStates[i]; const FBXMesh& mesh = geometry.meshes.at(i); From 93baad73873eb1de6fd0745dd6d430464563293d Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 9 Aug 2018 14:35:44 -0700 Subject: [PATCH 033/545] removed unnecessary computation of head height from eye position code --- .../avatars-renderer/src/avatars-renderer/SkeletonModel.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp index 11bad6c1b8..1ec58fd704 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp @@ -300,7 +300,6 @@ bool SkeletonModel::getEyeModelPositions(glm::vec3& firstEyePosition, glm::vec3& getJointRotation(geometry.headJointIndex, headRotation); const float EYES_FORWARD_HEAD_ONLY = 0.30f; const float EYE_SEPARATION = 0.1f; - float headHeight = glm::distance(neckPosition, headPosition); firstEyePosition = baseEyePosition + headRotation * glm::vec3(EYE_SEPARATION, 0.0f, EYES_FORWARD_HEAD_ONLY); secondEyePosition = baseEyePosition + headRotation * glm::vec3(-EYE_SEPARATION, 0.0f, EYES_FORWARD_HEAD_ONLY); return true; From 353121be7d374ae58061ac55db8106a60b0d163c Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Thu, 9 Aug 2018 16:29:37 -0700 Subject: [PATCH 034/545] making some changes --- interface/resources/images/loadingBar_v1.png | Bin 0 -> 20323 bytes scripts/system/interstitialPage.js | 38 ++++++++++--------- 2 files changed, 21 insertions(+), 17 deletions(-) create mode 100644 interface/resources/images/loadingBar_v1.png diff --git a/interface/resources/images/loadingBar_v1.png b/interface/resources/images/loadingBar_v1.png new file mode 100644 index 0000000000000000000000000000000000000000..b5c77054c4b2e185da0992a2237d2eb80d9033fc GIT binary patch literal 20323 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 X0pQ4zmm92`e;f&>qNQA^X!iD>8RVDV literal 0 HcmV?d00001 diff --git a/scripts/system/interstitialPage.js b/scripts/system/interstitialPage.js index 76900bd77c..ae1f71d0dd 100644 --- a/scripts/system/interstitialPage.js +++ b/scripts/system/interstitialPage.js @@ -15,7 +15,7 @@ (function() { Script.include("/~/system/libraries/Xform.js"); var DEBUG = true; - var MAX_X_SIZE = 5; + var MAX_X_SIZE = 4; var EPSILON = 0.25; var isVisible = false; var STABILITY = 3.0; @@ -67,7 +67,6 @@ ignoreRayIntersection: true, drawInFront: true, grabbable: false, - parentID: MyAvatar.SELF_ID }); var anchorOverlay = Overlays.addOverlay("cube", { @@ -79,7 +78,7 @@ orientation: Quat.multiply(Quat.fromVec3Degrees({x: 0, y: 180, z: 0}), MyAvatar.orientation), solid: true, drawInFront: true, - parentID: MyAvatar.SELF_ID + parentID: loadingSphereID }); @@ -100,7 +99,6 @@ }); var domainText = ""; - var domainDescription = Overlays.addOverlay("text3d", { name: "Loading-Hostname", localPosition: { x: 0.0, y: 0.32, z: 0.0 }, @@ -150,7 +148,7 @@ var loadingBarPlacard = Overlays.addOverlay("image3d", { name: "Loading-Bar-Placard", - localPosition: { x: 0.0 , y: -0.99, z: 0.07 }, + localPosition: { x: 0.0, y: -0.99, z: 0.0 }, url: "http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/loadingBar_placard.png", alpha: 1, dimensions: { x: 4, y: 2.8}, @@ -165,10 +163,10 @@ var loadingBarProgress = Overlays.addOverlay("image3d", { name: "Loading-Bar-Progress", - localPosition: { x: 0.0 , y: -0.99, z: 0.0 }, - url: "http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/loadingBar_progress.png", + localPosition: { x: 0.0, y: -0.99, z: 0.0 }, + url: Script.resourcesPath() + "images/loadingBar_v1.png", alpha: 1, - dimensions: { x: 4, y: 2.8}, + dimensions: {x: 4, y: 2.8}, visible: isVisible, emissive: true, ignoreRayIntersection: false, @@ -187,6 +185,8 @@ var timer = null; var target = 0; + var connectionToDomainFailed = false; + function getAnchorLocalYOffset() { var loadingSpherePosition = Overlays.getProperty(loadingSphereID, "position"); @@ -219,6 +219,7 @@ startAudio(); target = 0; currentProgress = 0.1; + connectionToDomainFailed = false; timer = Script.setTimeout(update, BASIC_TIMER_INTERVAL_MS); } } @@ -313,9 +314,9 @@ MyAvatar.headOrientation = Quat.multiply(Quat.cancelOutRollAndPitch(MyAvatar.headOrientation), Quat.fromPitchYawRollDegrees(-3.0, 0, 0)); } - renderViewTask.getConfig("LightingModel")["enableAmbientLight"] = physicsEnabled; - renderViewTask.getConfig("LightingModel")["enableDirectionalLight"] = physicsEnabled; - renderViewTask.getConfig("LightingModel")["enablePointLight"] = physicsEnabled; + //renderViewTask.getConfig("LightingModel")["enableAmbientLight"] = physicsEnabled; + //renderViewTask.getConfig("LightingModel")["enableDirectionalLight"] = physicsEnabled; + //renderViewTask.getConfig("LightingModel")["enablePointLight"] = physicsEnabled; Overlays.editOverlay(loadingSphereID, mainSphereProperties); Overlays.editOverlay(loadingToTheSpotID, properties); Overlays.editOverlay(domainNameTextID, properties); @@ -350,7 +351,7 @@ progress += MAX_X_SIZE * (deltaTime / 1000); print(progress); var properties = { - localPosition: { x: -(progress / 1.98) + 2, y: -0.99, z: 0.0 }, + localPosition: { x: -(progress / 2) + 2, y: -0.99, z: 0.0 }, dimensions: { x: progress, y: 2.8 @@ -403,11 +404,11 @@ y: 2.8 } }; - + print("progress: " + currentProgress); Overlays.editOverlay(loadingBarProgress, properties); - if (physicsEnabled && (currentProgress >= (MAX_X_SIZE - EPSILON))) { + if (((physicsEnabled && (currentProgress >= (MAX_X_SIZE - EPSILON))) || connectionToDomainFailed)) { print("----------> ending <--------"); - updateOverlays(physicsEnabled); + updateOverlays((physicsEnabled || connectionToDomainFailed)); endAudio(); timer = null; return; @@ -418,7 +419,10 @@ Overlays.mouseReleaseOnOverlay.connect(clickedOnOverlay); location.hostChanged.connect(domainChanged); location.lookupResultsFinished.connect(function() { - print("connected: " + location.isConnected); + Script.setTimeout(function() { + print("location connected: " + location.isConnected); + connectionToDomainFailed = !location.isConnected; + }, 300); }); MyAvatar.sensorToWorldScaleChanged.connect(scaleInterstitialPage); @@ -433,7 +437,7 @@ updateOverlays(toggle); if (!toggle) { - Script.setTimeout(updateProgress, BASIC_TIMER_INTERVAL_MS); + //Script.setTimeout(updateProgress, BASIC_TIMER_INTERVAL_MS); } }); } From 46297c6b22aa4b1f2128ac4ef4acde155e1b4500 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Fri, 10 Aug 2018 10:20:39 -0700 Subject: [PATCH 035/545] interstitial page --- scripts/system/interstitialPage.js | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/scripts/system/interstitialPage.js b/scripts/system/interstitialPage.js index ae1f71d0dd..149e1e141b 100644 --- a/scripts/system/interstitialPage.js +++ b/scripts/system/interstitialPage.js @@ -67,11 +67,12 @@ ignoreRayIntersection: true, drawInFront: true, grabbable: false, + parentID: MyAvatar.SELF_ID }); var anchorOverlay = Overlays.addOverlay("cube", { dimensions: {x: 0.2, y: 0.2, z: 0.2}, - visible: true, + visible: false, grabbable: false, ignoreRayIntersection: true, localPosition: {x: 0.0, y: getAnchorLocalYOffset(), z: DEFAULT_Z_OFFSET }, @@ -314,9 +315,9 @@ MyAvatar.headOrientation = Quat.multiply(Quat.cancelOutRollAndPitch(MyAvatar.headOrientation), Quat.fromPitchYawRollDegrees(-3.0, 0, 0)); } - //renderViewTask.getConfig("LightingModel")["enableAmbientLight"] = physicsEnabled; - //renderViewTask.getConfig("LightingModel")["enableDirectionalLight"] = physicsEnabled; - //renderViewTask.getConfig("LightingModel")["enablePointLight"] = physicsEnabled; + renderViewTask.getConfig("LightingModel")["enableAmbientLight"] = physicsEnabled; + renderViewTask.getConfig("LightingModel")["enableDirectionalLight"] = physicsEnabled; + renderViewTask.getConfig("LightingModel")["enablePointLight"] = physicsEnabled; Overlays.editOverlay(loadingSphereID, mainSphereProperties); Overlays.editOverlay(loadingToTheSpotID, properties); Overlays.editOverlay(domainNameTextID, properties); @@ -350,15 +351,18 @@ progress += MAX_X_SIZE * (deltaTime / 1000); print(progress); + if (progress > MAX_X_SIZE) { + progress = 4; + } var properties = { - localPosition: { x: -(progress / 2) + 2, y: -0.99, z: 0.0 }, + localPosition: { x: 2.0 - (progress / 2), y: -0.99, z: -0.3 }, dimensions: { x: progress, y: 2.8 } }; - if (progress > MAX_X_SIZE) { + if (progress >= MAX_X_SIZE) { progress = 0; } @@ -398,7 +402,7 @@ } currentProgress = lerp(currentProgress, target, 0.2); var properties = { - localPosition: { x: -(currentProgress / 2) + 2, y: 0.99, z: 5.45 }, + localPosition: { x: 2 - (currentProgress / 2), y: -0.99, z: -0.3 }, dimensions: { x: currentProgress, y: 2.8 From 75cc1c62c05b8c9e6b52d8b4166fda533c72bbe6 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Fri, 10 Aug 2018 16:53:34 -0700 Subject: [PATCH 036/545] mostly done interstitial page --- .../resources/images/loadingBar_placard.png | Bin 0 -> 2737 bytes .../resources/images/loadingBar_progress.png | Bin 0 -> 20396 bytes interface/resources/images/loadingBar_v1.png | Bin 20323 -> 0 bytes interface/src/Application.cpp | 11 ++++-- interface/src/Application.h | 2 +- interface/src/Menu.cpp | 1 + scripts/defaultScripts.js | 3 +- scripts/system/interstitialPage.js | 37 ++++++++++-------- 8 files changed, 32 insertions(+), 22 deletions(-) create mode 100644 interface/resources/images/loadingBar_placard.png create mode 100644 interface/resources/images/loadingBar_progress.png delete mode 100644 interface/resources/images/loadingBar_v1.png diff --git a/interface/resources/images/loadingBar_placard.png b/interface/resources/images/loadingBar_placard.png new file mode 100644 index 0000000000000000000000000000000000000000..9fd4c9e71f433d71be2c220d29e30e938abc3a8c GIT binary patch literal 2737 zcmbVOYgAL&6+S_Mk%u^n;AkCU5C;bH4hac)pahUA6fsj&#E{%vBm>C}Nq_(%_&}tH zTA3+ON5Nu!R*$r%{NYL|Ba#!@Hz%4sN7g zi^EDK99*ld+XHJ@JMVBqJ*)21Ueof(eDQXT5Hy46T5gz^>v0U{oQ4k^{YD5Ym znLr}SWN2L0fK}=!_x<=`;o-{A_~laDI(?^ z&-?JyAbN=ZdMb?>#OIUA!TwAV&7U6X8c_-mBx$Y+A`=ibqDnv%*q|V+ceGS4LDEz{=n1_Im=7zZsjwtOiO8_l6tkr7 zF)yZxDRdEuil;#o2A)c$#p6XJKR>*P?hi?*P`p2dPQtyzOa9-~5xH145v`N|sGGU1 zD1HdK{H_bQ*zfxYmPt5$$OaBaWtl?@bIaIu`Ww7wkM>TkZk1gtC(Wj24*_J1TZ#ahTl8wL3ZEH66R1oH| zWLiy!7l2E$afSq4eo1%q!YcefedhrHN{+SjUZynX-6x+Dx87dcnYHKfMi8 zbT7!69fpcH9-#TyV&tH1JkVY|~ZKbPSH$6b68j77A8h zmA;#0kmxM`x*DFmq;Yj4&tpP1IMP;@*i(59M4}nK@@T(h`_5=Kfg+FfiHv^=jhQ+h z-td^N3$1SLvJG^bA-2p6vtKeeatGr+E*jRao&IiV);{d|64PI8slL9fK2N;87*tFV zLEG)G@Hexy&xFyyNwo$&BKDEsz~$x+oARD2rf*!@U|Hc%40)2?01nx@b(=jB9Ly=6 z=6L{+hP(pxXR3T_#`ofVCwr#Pf0l}5E@><+ExlD;K9PQ9B(?t4r@$3W>n7!>FcA}} z8y{EdU-joGq2?T=k zge4}{W>J&n7S4Qb9oJW}@?K@DW07`nE+?`XwhS$U>Kz zgYx^6qsbqeFSQH9wNx+;q4kj8b-cj7f8cNVr@KjmULYWK@ZnNN)8!g*r_kJy>vpt* z(KV81t%LJIV+1l&d}>C>t~3_)C)$UMk;5DJlUcaU4ZXbjPH*c()HB=GMBmxU{ zBB#MJPI{V{SP*=Jl(6|Gngu5U=6HaG_j(7bKYQUrrfyQIvTLl}lV)mjcLD&=ib2Y> z^VR7`$?hP_T`xfIXwcWzA(Pu^>b4)Ne=`q&#tI+X&s(p}X8y@G&=mB{9)O%NH=E~E ze{swaPOU`|2_D8*X7;env*SX00Kj4WWFG;vHoqR<->D^_j0d}qRb|2-dk8U#S6!Dc zRhM{}e+dAHOZsDDKkn$!uYq^gX4>KbRMpeboNnOy4R(JX1HQ^Hz3(1fhmM7*JPRg0 zqf+<0j|k+w4Od+qfB&Ej+;zWzJ}z>ao@*!j0dGZDv)NsmW5SN?V1Nb~MRRBc0p zIc{%f?LfHoSnOx7jg}b(lmSA+Q09uAV0Gc`p{-9&R9}x;dC4u-eabS4GM&Ybx_onI z+mRblhQY@bcOS%rj;(QM#?|YG%c?o9^<^!6Q0G|0xrz1{{dc}V0h_k0Y8Nd0BDis& zq-e~vC*xq&ii&IVu_v>|$## z4d)zx(|l?qwSHQhNjp_mn2wg<3)hR*V!7uPIOD&-R18Hl?_R>p7}#uXYUnT)JkaUb zAB=Vi_Hu8|UhE^+i+c;0%W6K^X%r`w6$}+!aucYoqBhyXr?szzznJ!|?S=x}RX&FL zlEjorn++TH<>ux-*bL4*=Qz%MU6hyA rCh-3_{NLiN_rMP*e&o{V7|zDn0e-CSeh1(ji#iw<9Ko+#AGhz{XO8;| literal 0 HcmV?d00001 diff --git a/interface/resources/images/loadingBar_progress.png b/interface/resources/images/loadingBar_progress.png new file mode 100644 index 0000000000000000000000000000000000000000..2b1fb089d97f0acce5cfe62a07075328ee6316f2 GIT binary patch literal 20396 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 literal 0 HcmV?d00001 diff --git a/interface/resources/images/loadingBar_v1.png b/interface/resources/images/loadingBar_v1.png deleted file mode 100644 index b5c77054c4b2e185da0992a2237d2eb80d9033fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20323 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 X0pQ4zmm92`e;f&>qNQA^X!iD>8RVDV diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index cac201f34b..12a3ebf887 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2973,6 +2973,9 @@ void Application::initializeUi() { if (_window && _window->isFullScreen()) { setFullscreen(nullptr, true); } + + + setIsInterstitialMode(true); } @@ -3451,13 +3454,15 @@ bool Application::isServerlessMode() const { } bool Application::isInterstitialMode() const { - return _interstitialMode; + bool interstitialModeEnabled = Menu::getInstance()->isOptionChecked("Enable Interstitial"); + return interstitialModeEnabled ? _interstitialMode : false; } void Application::setIsInterstitialMode(bool interstitialMode) { - if (_interstitialMode != interstitialMode) { - qDebug() << "-------> interstitial mode changed: " << _interstitialMode << " ------------> "; + bool interstitialModeEnabled = Menu::getInstance()->isOptionChecked("Enable Interstitial"); + if (_interstitialMode != interstitialMode && interstitialModeEnabled) { _interstitialMode = interstitialMode; + qDebug() << "-------> interstitial mode changed: " << _interstitialMode << " ------------> "; emit interstitialModeChanged(_interstitialMode); } } diff --git a/interface/src/Application.h b/interface/src/Application.h index 88aea0379f..856e2d199e 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -631,7 +631,7 @@ private: QSet _keysPressed; bool _enableProcessOctreeThread; - bool _interstitialMode { true }; + bool _interstitialMode { false }; OctreePacketProcessor _octreeProcessor; EntityEditPacketSender _entityEditSender; diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 130c2c0b89..9b0e8d83c1 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -781,6 +781,7 @@ Menu::Menu() { // Developer > Show Overlays addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::Overlays, 0, true); + addCheckableActionToQMenuAndActionHash(developerMenu, "Enable Interstitial", 0, false); #if 0 /// -------------- REMOVED FOR NOW -------------- addDisabledActionAndSeparator(navigateMenu, "History"); diff --git a/scripts/defaultScripts.js b/scripts/defaultScripts.js index 31510831c8..c333a0c8c2 100644 --- a/scripts/defaultScripts.js +++ b/scripts/defaultScripts.js @@ -34,8 +34,7 @@ var DEFAULT_SCRIPTS_COMBINED = [ "system/emote.js" ]; var DEFAULT_SCRIPTS_SEPARATE = [ - "system/controllers/controllerScripts.js", - "system/interstitialPage.js" + "system/controllers/controllerScripts.js" //"system/chat.js" ]; diff --git a/scripts/system/interstitialPage.js b/scripts/system/interstitialPage.js index 149e1e141b..87f415130f 100644 --- a/scripts/system/interstitialPage.js +++ b/scripts/system/interstitialPage.js @@ -15,8 +15,8 @@ (function() { Script.include("/~/system/libraries/Xform.js"); var DEBUG = true; - var MAX_X_SIZE = 4; - var EPSILON = 0.25; + var MAX_X_SIZE = 3.8; + var EPSILON = 0.01; var isVisible = false; var STABILITY = 3.0; var VOLUME = 0.4; @@ -149,8 +149,8 @@ var loadingBarPlacard = Overlays.addOverlay("image3d", { name: "Loading-Bar-Placard", - localPosition: { x: 0.0, y: -0.99, z: 0.0 }, - url: "http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/loadingBar_placard.png", + localPosition: { x: 0.0, y: -0.99, z: 0.3 }, + url: Script.resourcesPath() + "images/loadingBar_placard.png", alpha: 1, dimensions: { x: 4, y: 2.8}, visible: isVisible, @@ -164,10 +164,10 @@ var loadingBarProgress = Overlays.addOverlay("image3d", { name: "Loading-Bar-Progress", - localPosition: { x: 0.0, y: -0.99, z: 0.0 }, - url: Script.resourcesPath() + "images/loadingBar_v1.png", + localPosition: { x: 0.0, y: -0.90, z: 0.0 }, + url: Script.resourcesPath() + "images/loadingBar_progress.png", alpha: 1, - dimensions: {x: 4, y: 2.8}, + dimensions: {x: 3.8, y: 2.8}, visible: isVisible, emissive: true, ignoreRayIntersection: false, @@ -285,7 +285,7 @@ } } - var THE_PLACE = "hifi://TheSpot"; + var THE_PLACE = "hifi://TheSpot-dev"; function clickedOnOverlay(overlayID, event) { print(overlayID + " other: " + loadingToTheSpotID); if (loadingToTheSpotID === overlayID) { @@ -309,6 +309,11 @@ visible: !physicsEnabled }; + var loadingBarProperties = { + dimensions: { x: 0.0, y: 2.8 }, + visible: !physicsEnabled + }; + // Menu.setIsOptionChecked("Show Overlays", physicsEnabled); if (!HMD.active) { @@ -324,7 +329,7 @@ Overlays.editOverlay(domainDescription, domainTextProperties); Overlays.editOverlay(domainToolTip, properties); Overlays.editOverlay(loadingBarPlacard, properties); - Overlays.editOverlay(loadingBarProgress, properties); + Overlays.editOverlay(loadingBarProgress, loadingBarProperties); Camera.mode = "first person"; } @@ -349,13 +354,13 @@ lastInterval = thisInterval; timeElapsed += deltaTime; - progress += MAX_X_SIZE * (deltaTime / 1000); - print(progress); + progress += (deltaTime / 1000); if (progress > MAX_X_SIZE) { - progress = 4; + progress = MAX_X_SIZE; } + var properties = { - localPosition: { x: 2.0 - (progress / 2), y: -0.99, z: -0.3 }, + localPosition: { x: (1.85 - (progress / 2) - (-0.029 * (progress / MAX_X_SIZE))), y: -0.935, z: 0.0 }, dimensions: { x: progress, y: 2.8 @@ -402,7 +407,7 @@ } currentProgress = lerp(currentProgress, target, 0.2); var properties = { - localPosition: { x: 2 - (currentProgress / 2), y: -0.99, z: -0.3 }, + localPosition: { x: (1.85 - (progress / 2) - (-0.029 * (progress / MAX_X_SIZE))), y: -0.935, z: 0.0 }, dimensions: { x: currentProgress, y: 2.8 @@ -410,7 +415,7 @@ }; print("progress: " + currentProgress); Overlays.editOverlay(loadingBarProgress, properties); - if (((physicsEnabled && (currentProgress >= (MAX_X_SIZE - EPSILON))) || connectionToDomainFailed)) { + if ((physicsEnabled && (currentProgress >= (MAX_X_SIZE - EPSILON)))) { print("----------> ending <--------"); updateOverlays((physicsEnabled || connectionToDomainFailed)); endAudio(); @@ -441,7 +446,7 @@ updateOverlays(toggle); if (!toggle) { - //Script.setTimeout(updateProgress, BASIC_TIMER_INTERVAL_MS); + // Script.setTimeout(updateProgress, BASIC_TIMER_INTERVAL_MS); } }); } From c2612af7a8550e301a4861302cb6a9ae0cd9fc46 Mon Sep 17 00:00:00 2001 From: amantley Date: Fri, 10 Aug 2018 17:10:33 -0700 Subject: [PATCH 037/545] changed the spine stretch limit, will check the scale implications next --- interface/src/avatar/MyAvatar.cpp | 1 + libraries/shared/src/AvatarConstants.h | 2 +- scripts/developer/objectOrientedStep.js | 683 ++++++++++++++++++++++++ 3 files changed, 685 insertions(+), 1 deletion(-) create mode 100644 scripts/developer/objectOrientedStep.js diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 0d7b00da78..db0c683632 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -3692,6 +3692,7 @@ void MyAvatar::FollowHelper::prePhysicsUpdate(MyAvatar& myAvatar, const glm::mat setForceActivateRotation(false); } if (!isActive(Horizontal) && getForceActivateHorizontal()) { + qCDebug(interfaceapp) << "called the recentering from script"; activate(Horizontal); setForceActivateHorizontal(false); } diff --git a/libraries/shared/src/AvatarConstants.h b/libraries/shared/src/AvatarConstants.h index d9b26927e2..6b35a45f4c 100644 --- a/libraries/shared/src/AvatarConstants.h +++ b/libraries/shared/src/AvatarConstants.h @@ -34,7 +34,7 @@ const float DEFAULT_HANDS_ANGULAR_VELOCITY_STEPPING_THRESHOLD = 3.3f; const float DEFAULT_HEAD_VELOCITY_STEPPING_THRESHOLD = 0.18f; const float DEFAULT_HEAD_PITCH_STEPPING_TOLERANCE = 7.0f; const float DEFAULT_HEAD_ROLL_STEPPING_TOLERANCE = 7.0f; -const float DEFAULT_AVATAR_SPINE_STRETCH_LIMIT = 0.07f; +const float DEFAULT_AVATAR_SPINE_STRETCH_LIMIT = 0.03f; const float DEFAULT_AVATAR_FORWARD_DAMPENING_FACTOR = 0.5f; const float DEFAULT_AVATAR_LATERAL_DAMPENING_FACTOR = 2.0f; const float DEFAULT_AVATAR_HIPS_MASS = 40.0f; diff --git a/scripts/developer/objectOrientedStep.js b/scripts/developer/objectOrientedStep.js new file mode 100644 index 0000000000..4eca1fb115 --- /dev/null +++ b/scripts/developer/objectOrientedStep.js @@ -0,0 +1,683 @@ +/* jslint bitwise: true */ + +/* global Script, Vec3, MyAvatar, Tablet, Messages, Quat, +DebugDraw, Mat4, Entities, Xform, Controller, Camera, console, document*/ + +Script.registerValue("STEPAPP", true); +var CENTIMETERSPERMETER = 100.0; +var LEFT = 0; +var RIGHT = 1; +var INCREASING = 1.0; +var DECREASING = -1.0; +var DEFAULT_AVATAR_HEIGHT = 1.64; +var TABLET_BUTTON_NAME = "STEP"; +var CHANGE_OF_BASIS_ROTATION = { x: 0, y: 1, z: 0, w: 0 }; +// in meters (mostly) +var DEFAULT_ANTERIOR = 0.04; +var DEFAULT_POSTERIOR = 0.06; +var DEFAULT_LATERAL = 0.10; +var DEFAULT_HEIGHT_DIFFERENCE = 0.02; +var DEFAULT_ANGULAR_VELOCITY = 0.3; +var DEFAULT_HAND_VELOCITY = 0.4; +var DEFAULT_ANGULAR_HAND_VELOCITY = 3.3; +var DEFAULT_HEAD_VELOCITY = 0.14; +var DEFAULT_LEVEL_PITCH = 7; +var DEFAULT_LEVEL_ROLL = 7; +var DEFAULT_DIFF = 0.0; +var DEFAULT_DIFF_EULERS = { x: 0.0, y: 0.0, z: 0.0 }; +var DEFAULT_HIPS_POSITION; +var DEFAULT_HEAD_POSITION; +var DEFAULT_TORSO_LENGTH; +var SPINE_STRETCH_LIMIT = 0.02; + +var VELOCITY_EPSILON = 0.02; +var AVERAGING_RATE = 0.03; +var HEIGHT_AVERAGING_RATE = 0.01; +var STEP_TIME_SECS = 0.2; +var MODE_SAMPLE_LENGTH = 100; +var RESET_MODE = false; +var HEAD_TURN_THRESHOLD = 25.0; +var NO_SHARED_DIRECTION = -0.98; +var LOADING_DELAY = 500; +var FAILSAFE_TIMEOUT = 2.5; + +var debugDrawBase = true; +var activated = false; +var documentLoaded = false; +var failsafeFlag = false; +var failsafeSignalTimer = -1.0; +var stepTimer = -1.0; + + +var modeArray = new Array(MODE_SAMPLE_LENGTH); +var modeHeight = -10.0; + +var handPosition; +var handOrientation; +var hands = []; +var hipToHandAverage = []; +var handDotHead = []; +var headAverageOrientation = MyAvatar.orientation; +var headPoseAverageOrientation = { x: 0, y: 0, z: 0, w: 1 }; +var averageHeight = 1.0; +var headEulers = { x: 0.0, y: 0.0, z: 0.0 }; +var headAverageEulers = { x: 0.0, y: 0.0, z: 0.0 }; +var headAveragePosition = { x: 0, y: 0.4, z: 0 }; +var frontLeft = { x: -DEFAULT_LATERAL, y: 0, z: -DEFAULT_ANTERIOR }; +var frontRight = { x: DEFAULT_LATERAL, y: 0, z: -DEFAULT_ANTERIOR }; +var backLeft = { x: -DEFAULT_LATERAL, y: 0, z: DEFAULT_POSTERIOR }; +var backRight = { x: DEFAULT_LATERAL, y: 0, z: DEFAULT_POSTERIOR }; + + +// define state readings constructor +function StateReading(headPose, rhandPose, lhandPose, backLength, diffFromMode, diffFromAverageHeight, diffFromAveragePosition, + diffFromAverageEulers) { + this.headPose = headPose; + this.rhandPose = rhandPose; + this.lhandPose = lhandPose; + this.backLength = backLength; + this.diffFromMode = diffFromMode; + this.diffFromAverageHeight = diffFromAverageHeight; + this.diffFromAveragePosition = diffFromAveragePosition; + this.diffFromAverageEulers = diffFromAverageEulers; +} + +// define current state readings object for holding tracker readings and current differences from averages +var currentStateReadings = new StateReading(Controller.getPoseValue(Controller.Standard.Head), + Controller.getPoseValue(Controller.Standard.RightHand), Controller.getPoseValue(Controller.Standard.LeftHand), + DEFAULT_TORSO_LENGTH, DEFAULT_DIFF, DEFAULT_DIFF, DEFAULT_DIFF, DEFAULT_DIFF_EULERS); + +// declare the checkbox constructor +function AppCheckbox(type,id,eventType,isChecked) { + this.type = type; + this.id = id; + this.eventType = eventType; + this.data = {value: isChecked}; +} + +// define the checkboxes in the html file +var usingAverageHeight = new AppCheckbox("checkboxtick", "runningAverageHeightCheck", "onRunningAverageHeightCheckBox", + false); +var usingModeHeight = new AppCheckbox("checkboxtick","modeCheck","onModeCheckBox",true); +var usingBaseOfSupport = new AppCheckbox("checkboxtick","baseOfSupportCheck","onBaseOfSupportCheckBox",true); +var usingAverageHeadPosition = new AppCheckbox("checkboxtick", "headAveragePositionCheck", "onHeadAveragePositionCheckBox", + false); + +var checkBoxArray = new Array(usingAverageHeight,usingModeHeight,usingBaseOfSupport,usingAverageHeadPosition); + +// declare the html slider constructor +function AppProperty(name, type, eventType, signalType, setFunction, initValue, convertToThreshold, convertToSlider, signalOn) { + this.name = name; + this.type = type; + this.eventType = eventType; + this.signalType = signalType; + this.setValue = setFunction; + this.value = initValue; + this.get = function () { + return this.value; + }; + this.convertToThreshold = convertToThreshold; + this.convertToSlider = convertToSlider; + this.signalOn = signalOn; +} + +// define the sliders +var frontBaseProperty = new AppProperty("#anteriorBase-slider", "slider", "onAnteriorBaseSlider", "frontSignal", + setAnteriorDistance, DEFAULT_ANTERIOR, function (num) { + return convertToMeters(num); + }, function (num) { + return convertToCentimeters(num); + },true); +var backBaseProperty = new AppProperty("#posteriorBase-slider", "slider", "onPosteriorBaseSlider", "backSignal", + setPosteriorDistance, DEFAULT_POSTERIOR, function (num) { + return convertToMeters(num); + }, function (num) { + return convertToCentimeters(num); + }, true); +var lateralBaseProperty = new AppProperty("#lateralBase-slider", "slider", "onLateralBaseSlider", "lateralSignal", + setLateralDistance, DEFAULT_LATERAL, function (num) { + return convertToMeters(num); + }, function (num) { + return convertToCentimeters(num); + }, true); +var headAngularVelocityProperty = new AppProperty("#angularVelocityHead-slider", "slider", "onAngularVelocitySlider", + "angularHeadSignal", setAngularThreshold, DEFAULT_ANGULAR_VELOCITY, function (num) { + var base = 4; + var shift = 2; + return convertExponential(base, num, DECREASING, shift); + }, function (num) { + var base = 4; + var shift = 2; + return convertLog(base, num, DECREASING, shift); + }, true); +var heightDifferenceProperty = new AppProperty("#heightDifference-slider", "slider", "onHeightDifferenceSlider", "heightSignal", + setHeightThreshold, DEFAULT_HEIGHT_DIFFERENCE, function (num) { + return convertToMeters(-num); + }, function (num) { + return convertToCentimeters(-num); + }, true); +var handsVelocityProperty = new AppProperty("#handsVelocity-slider", "slider", "onHandsVelocitySlider", "handVelocitySignal", + setHandVelocityThreshold, DEFAULT_HAND_VELOCITY, function (num) { + return num; + }, function (num) { + return num; + }, true); +var handsAngularVelocityProperty = new AppProperty("#handsAngularVelocity-slider", "slider", "onHandsAngularVelocitySlider", + "handAngularSignal", setHandAngularVelocityThreshold, DEFAULT_ANGULAR_HAND_VELOCITY, function (num) { + var base = 7; + var shift = 2; + return convertExponential(base, num, DECREASING, shift); + }, function (num) { + var base = 7; + var shift = 2; + return convertLog(base, num, DECREASING, shift); + }, true); +var headVelocityProperty = new AppProperty("#headVelocity-slider", "slider", "onHeadVelocitySlider", "headVelocitySignal", + setHeadVelocityThreshold, DEFAULT_HEAD_VELOCITY, function (num) { + var base = 2; + var shift = 0; + return convertExponential(base, num, INCREASING, shift); + }, function (num) { + var base = 2; + var shift = 0; + return convertLog(base, num, INCREASING, shift); + }, true); +var headPitchProperty = new AppProperty("#headPitch-slider", "slider", "onHeadPitchSlider", "headPitchSignal", + setHeadPitchThreshold, DEFAULT_LEVEL_PITCH, function (num) { + var base = 2.5; + var shift = 5; + return convertExponential(base, num, DECREASING, shift); + }, function (num) { + var base = 2.5; + var shift = 5; + return convertLog(base, num, DECREASING, shift); + }, true); +var headRollProperty = new AppProperty("#headRoll-slider", "slider", "onHeadRollSlider", "headRollSignal", setHeadRollThreshold, + DEFAULT_LEVEL_ROLL, function (num) { + var base = 2.5; + var shift = 5; + return convertExponential(base, num, DECREASING, shift); + }, function (num) { + var base = 2.5; + var shift = 5; + return convertLog(base, num, DECREASING, shift); + }, true); + +var propArray = new Array(frontBaseProperty, backBaseProperty, lateralBaseProperty, headAngularVelocityProperty, + heightDifferenceProperty, handsVelocityProperty, handsAngularVelocityProperty, headVelocityProperty, headPitchProperty, + headRollProperty); + +// var HTML_URL = Script.resolvePath("http://hifi-content.s3.amazonaws.com/angus/stepApp/stepApp.html"); +var HTML_URL = Script.resolvePath("http://hifi-content.s3.amazonaws.com/angus/stepApp/stepAppExtra.html"); +var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); + +function manageClick() { + if (activated) { + tablet.gotoHomeScreen(); + } else { + tablet.gotoWebScreen(HTML_URL); + } +} + +var tabletButton = tablet.addButton({ + text: TABLET_BUTTON_NAME, + icon: Script.resolvePath("http://hifi-content.s3.amazonaws.com/angus/stepApp/foot.svg"), + activeIcon: Script.resolvePath("http://hifi-content.s3.amazonaws.com/angus/stepApp/foot.svg") +}); + +function drawBase() { + // transform corners into world space, for rendering. + var worldPointLf = Vec3.sum(MyAvatar.position,Vec3.multiplyQbyV(MyAvatar.orientation, frontLeft)); + var worldPointRf = Vec3.sum(MyAvatar.position,Vec3.multiplyQbyV(MyAvatar.orientation, frontRight)); + var worldPointLb = Vec3.sum(MyAvatar.position,Vec3.multiplyQbyV(MyAvatar.orientation, backLeft)); + var worldPointRb = Vec3.sum(MyAvatar.position,Vec3.multiplyQbyV(MyAvatar.orientation, backRight)); + + var GREEN = { r: 0, g: 1, b: 0, a: 1 }; + // draw border + DebugDraw.drawRay(worldPointLf, worldPointRf, GREEN); + DebugDraw.drawRay(worldPointRf, worldPointRb, GREEN); + DebugDraw.drawRay(worldPointRb, worldPointLb, GREEN); + DebugDraw.drawRay(worldPointLb, worldPointLf, GREEN); +} + +function onKeyPress(event) { + if (event.text === "'") { + // when the sensors are reset, then reset the mode. + RESET_MODE = false; + } +} + +function onWebEventReceived(msg) { + var message = JSON.parse(msg); + print(" we have a message from html dialog " + message.type); + propArray.forEach(function (prop) { + if (prop.eventType === message.type) { + prop.setValue(prop.convertToThreshold(message.data.value)); + print("message from " + prop.name); + // break; + } + }); + checkBoxArray.forEach(function(cbox) { + if (cbox.eventType === message.type) { + cbox.data.value = message.data.value; + // break; + } + }); + if (message.type === "onCreateStepApp") { + print("document loaded"); + documentLoaded = true; + Script.setTimeout(initAppForm, LOADING_DELAY); + } +} + +function initAppForm() { + print("step app is loaded: " + documentLoaded); + if (documentLoaded === true) { + propArray.forEach(function (prop) { + tablet.emitScriptEvent(JSON.stringify({ + "type": "trigger", + "id": prop.signalType, + "data": { "value": "green" } + })); + tablet.emitScriptEvent(JSON.stringify({ + "type": "slider", + "id": prop.name, + "data": { "value": prop.convertToSlider(prop.value) } + })); + }); + checkBoxArray.forEach(function (cbox) { + tablet.emitScriptEvent(JSON.stringify({ + "type": "checkboxtick", + "id": cbox.id, + "data": { "value": cbox.data.value } + })); + }); + } +} + +function updateSignalColors() { + + // force the updates by running the threshold comparisons + withinBaseOfSupport(currentStateReadings.headPose.translation); + withinThresholdOfStandingHeightMode(currentStateReadings.diffFromMode); + headAngularVelocityBelowThreshold(currentStateReadings.headPose.angularVelocity); + handDirectionMatchesHeadDirection(currentStateReadings.lhandPose, currentStateReadings.rhandPose); + handAngularVelocityBelowThreshold(currentStateReadings.lhandPose, currentStateReadings.rhandPose); + headVelocityGreaterThanThreshold(Vec3.length(currentStateReadings.headPose.velocity)); + headMovedAwayFromAveragePosition(currentStateReadings.diffFromAveragePosition); + headLowerThanHeightAverage(currentStateReadings.diffFromAverageHeight); + isHeadLevel(currentStateReadings.diffFromAverageEulers); + + propArray.forEach(function (prop) { + if (prop.signalOn) { + tablet.emitScriptEvent(JSON.stringify({ "type": "trigger", "id": prop.signalType, "data": { "value": "green" } })); + } else { + tablet.emitScriptEvent(JSON.stringify({ "type": "trigger", "id": prop.signalType, "data": { "value": "red" } })); + } + }); +} + +function onScreenChanged(type, url) { + print("Screen changed"); + if (type === "Web" && url === HTML_URL) { + if (!activated) { + // hook up to event bridge + tablet.webEventReceived.connect(onWebEventReceived); + print("after connect web event"); + MyAvatar.hmdLeanRecenterEnabled = false; + + } + activated = true; + } else { + if (activated) { + // disconnect from event bridge + tablet.webEventReceived.disconnect(onWebEventReceived); + documentLoaded = false; + } + activated = false; + } +} + +function getLog(x, y) { + return Math.log(y) / Math.log(x); +} + +function noConversion(num) { + return num; +} + +function convertLog(base, num, direction, shift) { + return direction * getLog(base, (num + 1.0)) + shift; +} + +function convertExponential(base, num, direction, shift) { + return Math.pow(base, (direction*num + shift)) - 1.0; +} + +function convertToCentimeters(num) { + return num * CENTIMETERSPERMETER; +} + +function convertToMeters(num) { + print("convert to meters " + num); + return num / CENTIMETERSPERMETER; +} + +function isInsideLine(a, b, c) { + return (((b.x - a.x)*(c.z - a.z) - (b.z - a.z)*(c.x - a.x)) > 0); +} + +function setAngularThreshold(num) { + headAngularVelocityProperty.value = num; + print("angular threshold " + headAngularVelocityProperty.get()); +} + +function setHeadRollThreshold(num) { + headRollProperty.value = num; + print("head roll threshold " + headRollProperty.get()); +} + +function setHeadPitchThreshold(num) { + headPitchProperty.value = num; + print("head pitch threshold " + headPitchProperty.get()); +} + +function setHeightThreshold(num) { + heightDifferenceProperty.value = num; + print("height threshold " + heightDifferenceProperty.get()); +} + +function setLateralDistance(num) { + lateralBaseProperty.value = num; + frontLeft.x = -lateralBaseProperty.get(); + frontRight.x = lateralBaseProperty.get(); + backLeft.x = -lateralBaseProperty.get(); + backRight.x = lateralBaseProperty.get(); + print("lateral distance " + lateralBaseProperty.get()); +} + +function setAnteriorDistance(num) { + frontBaseProperty.value = num; + frontLeft.z = -frontBaseProperty.get(); + frontRight.z = -frontBaseProperty.get(); + print("anterior distance " + frontBaseProperty.get()); +} + +function setPosteriorDistance(num) { + backBaseProperty.value = num; + backLeft.z = backBaseProperty.get(); + backRight.z = backBaseProperty.get(); + print("posterior distance " + backBaseProperty.get()); +} + +function setHandAngularVelocityThreshold(num) { + handsAngularVelocityProperty.value = num; + print("hand angular velocity threshold " + handsAngularVelocityProperty.get()); +} + +function setHandVelocityThreshold(num) { + handsVelocityProperty.value = num; + print("hand velocity threshold " + handsVelocityProperty.get()); +} + +function setHeadVelocityThreshold(num) { + headVelocityProperty.value = num; + print("headvelocity threshold " + headVelocityProperty.get()); +} + +function withinBaseOfSupport(pos) { + var userScale = 1.0; + frontBaseProperty.signalOn = !(isInsideLine(Vec3.multiply(userScale, frontLeft), Vec3.multiply(userScale, frontRight), pos)); + backBaseProperty.signalOn = !(isInsideLine(Vec3.multiply(userScale, backRight), Vec3.multiply(userScale, backLeft), pos)); + lateralBaseProperty.signalOn = !(isInsideLine(Vec3.multiply(userScale, frontRight), Vec3.multiply(userScale, backRight), pos) + && isInsideLine(Vec3.multiply(userScale, backLeft), Vec3.multiply(userScale, frontLeft), pos)); + return (!frontBaseProperty.signalOn && !backBaseProperty.signalOn && !lateralBaseProperty.signalOn); +} + +function withinThresholdOfStandingHeightMode(heightDiff) { + if (usingModeHeight.data.value) { + heightDifferenceProperty.signalOn = heightDiff < heightDifferenceProperty.get(); + return heightDifferenceProperty.signalOn; + } else { + return true; + } +} + +function headAngularVelocityBelowThreshold(headAngularVelocity) { + var angVel = Vec3.length({ x: headAngularVelocity.x, y: 0, z: headAngularVelocity.z }); + headAngularVelocityProperty.signalOn = angVel < headAngularVelocityProperty.get(); + return headAngularVelocityProperty.signalOn; +} + +function handDirectionMatchesHeadDirection(lhPose, rhPose) { + handsVelocityProperty.signalOn = ((handsVelocityProperty.get() < NO_SHARED_DIRECTION) || + ((!lhPose.valid || ((handDotHead[LEFT] > handsVelocityProperty.get()) && + (Vec3.length(lhPose.velocity) > VELOCITY_EPSILON))) && + (!rhPose.valid || ((handDotHead[RIGHT] > handsVelocityProperty.get()) && + (Vec3.length(rhPose.velocity) > VELOCITY_EPSILON))))); + return handsVelocityProperty.signalOn; +} + +function handAngularVelocityBelowThreshold(lhPose, rhPose) { + var xzRHandAngularVelocity = Vec3.length({ x: rhPose.angularVelocity.x, y: 0.0, z: rhPose.angularVelocity.z }); + var xzLHandAngularVelocity = Vec3.length({ x: lhPose.angularVelocity.x, y: 0.0, z: lhPose.angularVelocity.z }); + handsAngularVelocityProperty.signalOn = ((!rhPose.valid ||(xzRHandAngularVelocity < handsAngularVelocityProperty.get())) + && (!lhPose.valid || (xzLHandAngularVelocity < handsAngularVelocityProperty.get()))); + return handsAngularVelocityProperty.signalOn; +} + +function headVelocityGreaterThanThreshold(headVel) { + headVelocityProperty.signalOn = (headVel > headVelocityProperty.get()) || (headVelocityProperty.get() < VELOCITY_EPSILON); + return headVelocityProperty.signalOn; +} + +function headMovedAwayFromAveragePosition(headDelta) { + return !withinBaseOfSupport(headDelta) || !usingAverageHeadPosition.data.value; +} + +function headLowerThanHeightAverage(heightDiff) { + if (usingAverageHeight.data.value) { + print("head lower than height average"); + heightDifferenceProperty.signalOn = heightDiff < heightDifferenceProperty.get(); + return heightDifferenceProperty.signalOn; + } else { + return true; + } +} + +function isHeadLevel(diffEulers) { + headRollProperty.signalOn = Math.abs(diffEulers.z) < headRollProperty.get(); + headPitchProperty.signalOn = Math.abs(diffEulers.x) < headPitchProperty.get(); + return (headRollProperty.signalOn && headPitchProperty.signalOn); +} + +function findAverage(arr) { + var sum = arr.reduce(function (acc, val) { + return acc + val; + },0); + return sum / arr.length; +} + +function addToModeArray(arr,num) { + for (var i = 0 ;i < (arr.length - 1); i++) { + arr[i] = arr[i+1]; + } + arr[arr.length - 1] = (Math.floor(num*CENTIMETERSPERMETER))/CENTIMETERSPERMETER; +} + +function findMode(ary, currentMode, backLength, defaultBack, currentHeight) { + var numMapping = {}; + var greatestFreq = 0; + var mode; + ary.forEach(function (number) { + numMapping[number] = (numMapping[number] || 0) + 1; + if ((greatestFreq < numMapping[number]) || ((numMapping[number] === MODE_SAMPLE_LENGTH) && (number > currentMode) )) { + greatestFreq = numMapping[number]; + mode = number; + } + }); + if (mode > currentMode) { + return Number(mode); + } else { + if (!RESET_MODE && HMD.active) { + print("resetting the mode............................................. "); + print("resetting the mode............................................. "); + RESET_MODE = true; + var correction = 0.02; + return currentHeight - correction; + } else { + return currentMode; + } + } +} + +function update(dt) { + if (debugDrawBase) { + drawBase(); + } + // Update current state information + currentStateReadings.headPose = Controller.getPoseValue(Controller.Standard.Head); + currentStateReadings.rhandPose = Controller.getPoseValue(Controller.Standard.RightHand); + currentStateReadings.lhandPose = Controller.getPoseValue(Controller.Standard.LeftHand); + + // back length + var headMinusHipLean = Vec3.subtract(currentStateReadings.headPose.translation, DEFAULT_HIPS_POSITION); + currentStateReadings.backLength = Vec3.length(headMinusHipLean); + // print("back length and default " + currentStateReadings.backLength + " " + DEFAULT_TORSO_LENGTH); + + // mode height + addToModeArray(modeArray, currentStateReadings.headPose.translation.y); + modeHeight = findMode(modeArray, modeHeight, currentStateReadings.backLength, DEFAULT_TORSO_LENGTH, + currentStateReadings.headPose.translation.y); + currentStateReadings.diffFromMode = modeHeight - currentStateReadings.headPose.translation.y; + + // hand direction + var leftHandLateralPoseVelocity = currentStateReadings.lhandPose.velocity; + leftHandLateralPoseVelocity.y = 0.0; + var rightHandLateralPoseVelocity = currentStateReadings.rhandPose.velocity; + rightHandLateralPoseVelocity.y = 0.0; + var headLateralPoseVelocity = currentStateReadings.headPose.velocity; + headLateralPoseVelocity.y = 0.0; + handDotHead[LEFT] = Vec3.dot(Vec3.normalize(leftHandLateralPoseVelocity), Vec3.normalize(headLateralPoseVelocity)); + handDotHead[RIGHT] = Vec3.dot(Vec3.normalize(rightHandLateralPoseVelocity), Vec3.normalize(headLateralPoseVelocity)); + + // average head position + headAveragePosition = Vec3.mix(headAveragePosition, currentStateReadings.headPose.translation, AVERAGING_RATE); + currentStateReadings.diffFromAveragePosition = Vec3.subtract(currentStateReadings.headPose.translation, + headAveragePosition); + + // average height + averageHeight = currentStateReadings.headPose.translation.y * HEIGHT_AVERAGING_RATE + + averageHeight * (1.0 - HEIGHT_AVERAGING_RATE); + currentStateReadings.diffFromAverageHeight = Math.abs(currentStateReadings.headPose.translation.y - averageHeight); + + // eulers diff + headEulers = Quat.safeEulerAngles(currentStateReadings.headPose.rotation); + headAverageOrientation = Quat.slerp(headAverageOrientation, currentStateReadings.headPose.rotation, AVERAGING_RATE); + headAverageEulers = Quat.safeEulerAngles(headAverageOrientation); + currentStateReadings.diffFromAverageEulers = Vec3.subtract(headAverageEulers, headEulers); + + // headpose rig space is for determining when to recenter rotation. + var headPoseRigSpace = Quat.multiply(CHANGE_OF_BASIS_ROTATION, currentStateReadings.headPose.rotation); + headPoseAverageOrientation = Quat.slerp(headPoseAverageOrientation, headPoseRigSpace, AVERAGING_RATE); + var headPoseAverageEulers = Quat.safeEulerAngles(headPoseAverageOrientation); + + // make the signal colors reflect the current thresholds that have been crossed + updateSignalColors(); + print("the current back length is " + currentStateReadings.backLength + " " + DEFAULT_TORSO_LENGTH); + // Conditions for taking a step. + // 1. off the base of support. front, lateral, back edges. + // 2. head is not lower than the height mode value by more than the maxHeightChange tolerance + // 3. the angular velocity of the head is not greater than the threshold value + // ie this reflects the speed the head is rotating away from having up = (0,1,0) in Avatar frame.. + // 4. the hands velocity vector has the same direction as the head, within the given tolerance + // the tolerance is an acos value, -1 means the hands going in any direction will not block translating + // up to 1 where the hands velocity direction must exactly match that of the head. -1 threshold disables this condition. + // 5. the angular velocity xz magnitude for each hand is below the threshold value + // ie here this reflects the speed that each hand is rotating away from having up = (0,1,0) in Avatar frame. + // 6. head velocity is below step threshold + // 7. head has moved further than the threshold from the running average position of the head. + // 8. head height is not lower than the running average head height with a difference of maxHeightChange. + // 9. head's rotation in avatar space is not pitching or rolling greater than the pitch or roll thresholds + if (!withinBaseOfSupport(currentStateReadings.headPose.translation) && + withinThresholdOfStandingHeightMode(currentStateReadings.diffFromMode) && + headAngularVelocityBelowThreshold(currentStateReadings.headPose.angularVelocity) && + handDirectionMatchesHeadDirection(currentStateReadings.lhandPose, currentStateReadings.rhandPose) && + handAngularVelocityBelowThreshold(currentStateReadings.lhandPose, currentStateReadings.rhandPose) && + headVelocityGreaterThanThreshold(Vec3.length(currentStateReadings.headPose.velocity)) && + headMovedAwayFromAveragePosition(currentStateReadings.diffFromAveragePosition) && + headLowerThanHeightAverage(currentStateReadings.diffFromAverageHeight) && + isHeadLevel(currentStateReadings.diffFromAverageEulers)) { + + if (stepTimer < 0.0) { //!MyAvatar.isRecenteringHorizontally() + print("trigger recenter========================================================"); + MyAvatar.triggerHorizontalRecenter(); + stepTimer = STEP_TIME_SECS; + } + } else if ((currentStateReadings.backLength > (DEFAULT_TORSO_LENGTH + SPINE_STRETCH_LIMIT)) && + (failsafeSignalTimer < 0.0) && HMD.active) { + // do the failsafe recenter. + // failsafeFlag stops repeated setting of failsafe button color. + // RESET_MODE false forces a reset of the height + RESET_MODE = false; + failsafeFlag = true; + failsafeSignalTimer = FAILSAFE_TIMEOUT; + MyAvatar.triggerHorizontalRecenter(); + tablet.emitScriptEvent(JSON.stringify({ "type": "failsafe", "id": "failsafeSignal", "data": { "value": "green" } })); + // in fail safe we debug print the values that were blocking us. + print("failsafe debug---------------------------------------------------------------"); + propArray.forEach(function (prop) { + print(prop.name); + if (!prop.signalOn) { + print(prop.signalType + " contributed to failsafe call"); + } + }); + print("end failsafe debug---------------------------------------------------------------"); + + } + + if ((failsafeSignalTimer < 0.0) && failsafeFlag) { + failsafeFlag = false; + tablet.emitScriptEvent(JSON.stringify({ "type": "failsafe", "id": "failsafeSignal", "data": { "value": "orange" } })); + } + + stepTimer -= dt; + failsafeSignalTimer -= dt; + + if (!HMD.active) { + RESET_MODE = false; + } + + if (Math.abs(headPoseAverageEulers.y) > HEAD_TURN_THRESHOLD) { + // Turn feet + // MyAvatar.triggerRotationRecenter(); + // headPoseAverageOrientation = { x: 0, y: 0, z: 0, w: 1 }; + } +} + +function shutdownTabletApp() { + // GlobalDebugger.stop(); + tablet.removeButton(tabletButton); + if (activated) { + tablet.webEventReceived.disconnect(onWebEventReceived); + tablet.gotoHomeScreen(); + } + tablet.screenChanged.disconnect(onScreenChanged); +} + +tabletButton.clicked.connect(manageClick); +tablet.screenChanged.connect(onScreenChanged); + +Script.setTimeout(function() { + DEFAULT_HIPS_POSITION = MyAvatar.getAbsoluteDefaultJointTranslationInObjectFrame(MyAvatar.getJointIndex("Hips")); + DEFAULT_HEAD_POSITION = MyAvatar.getAbsoluteDefaultJointTranslationInObjectFrame(MyAvatar.getJointIndex("Head")); + DEFAULT_TORSO_LENGTH = Vec3.length(Vec3.subtract(DEFAULT_HEAD_POSITION, DEFAULT_HIPS_POSITION)); +},(4*LOADING_DELAY)); + +Script.update.connect(update); +Controller.keyPressEvent.connect(onKeyPress); +Script.scriptEnding.connect(function () { + MyAvatar.hmdLeanRecenterEnabled = true; + Script.update.disconnect(update); + shutdownTabletApp(); +}); From 9f289711cee9a850b643278b2c23da76a6c36665 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Fri, 17 Aug 2018 14:33:21 -0700 Subject: [PATCH 038/545] fixing scripting window visiblity and size issues --- scripts/developer/debugging/debugWindow.js | 25 ++++++++++++++-------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/scripts/developer/debugging/debugWindow.js b/scripts/developer/debugging/debugWindow.js index 9522676007..993ca49a40 100644 --- a/scripts/developer/debugging/debugWindow.js +++ b/scripts/developer/debugging/debugWindow.js @@ -23,7 +23,7 @@ if (scripts.length >= 2) { var qml = Script.resolvePath('debugWindow.qml'); var HMD_DEBUG_WINDOW_GEOMETRY_KEY = 'hmdDebugWindowGeometry'; -var hmdDebugWindowGeometryValue = Settings.getValue(HMD_DEBUG_WINDOW_GEOMETRY_KEY) +var hmdDebugWindowGeometryValue = Settings.getValue(HMD_DEBUG_WINDOW_GEOMETRY_KEY); var windowWidth = 400; var windowHeight = 900; @@ -34,12 +34,13 @@ var windowY = 0; if (hmdDebugWindowGeometryValue !== '') { var geometry = JSON.parse(hmdDebugWindowGeometryValue); - - windowWidth = geometry.width - windowHeight = geometry.height - windowX = geometry.x - windowY = geometry.y - hasPosition = true; + if ((geometry.x !== 0) && (geometry.y !== 0)) { + windowWidth = geometry.width; + windowHeight = geometry.height; + windowX = geometry.x; + windowY = geometry.y; + hasPosition = true; + } } var window = new OverlayWindow({ @@ -52,6 +53,12 @@ if (hasPosition) { window.setPosition(windowX, windowY); } +window.visibleChanged.connect(function() { + if (!window.visible) { + window.setVisible(true); + } +}); + window.closed.connect(function () { Script.stop(); }); var getFormattedDate = function() { @@ -93,10 +100,10 @@ Script.scriptEnding.connect(function () { y: window.position.y, width: window.size.x, height: window.size.y - }) + }); Settings.setValue(HMD_DEBUG_WINDOW_GEOMETRY_KEY, geometry); window.close(); -}) +}); }()); From d9b136cf5d3aa2bfb60058fc42175465bac7c317 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Mon, 20 Aug 2018 11:06:51 -0700 Subject: [PATCH 039/545] Read resources from other than the main directory --- libraries/fbx/src/GLTFReader.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libraries/fbx/src/GLTFReader.cpp b/libraries/fbx/src/GLTFReader.cpp index 300e6f4846..317342b886 100644 --- a/libraries/fbx/src/GLTFReader.cpp +++ b/libraries/fbx/src/GLTFReader.cpp @@ -935,7 +935,7 @@ FBXGeometry* GLTFReader::readGLTF(QByteArray& model, const QVariantHash& mapping } bool GLTFReader::readBinary(const QString& url, QByteArray& outdata) { - QUrl binaryUrl = _url.resolved(QUrl(url).fileName()); + QUrl binaryUrl = _url.resolved(url); qCDebug(modelformat) << "binaryUrl: " << binaryUrl << " OriginalUrl: " << _url; bool success; @@ -948,7 +948,7 @@ bool GLTFReader::doesResourceExist(const QString& url) { if (_url.isEmpty()) { return false; } - QUrl candidateUrl = _url.resolved(QUrl(url).fileName()); + QUrl candidateUrl = _url.resolved(url); return DependencyManager::get()->resourceExists(candidateUrl); } @@ -1001,8 +1001,9 @@ FBXTexture GLTFReader::getFBXTexture(const GLTFTexture& texture) { fbxtex.texcoordSet = 0; if (texture.defined["source"]) { - QString fname = QUrl(_file.images[texture.source].uri).fileName(); - QUrl textureUrl = _url.resolved(fname); + QString url = _file.images[texture.source].uri; + QString fname = QUrl(url).fileName(); + QUrl textureUrl = _url.resolved(url); qCDebug(modelformat) << "fname: " << fname; qCDebug(modelformat) << "textureUrl: " << textureUrl; qCDebug(modelformat) << "Url: " << _url; From 2261ad2bcbde983c607a4249477db4c7104d9dc6 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Mon, 20 Aug 2018 11:14:48 -0700 Subject: [PATCH 040/545] clean up the interstitial page --- interface/src/Application.cpp | 5 +-- scripts/system/interstitialPage.js | 58 ++++-------------------------- 2 files changed, 9 insertions(+), 54 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 12a3ebf887..89d1b24736 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3459,10 +3459,11 @@ bool Application::isInterstitialMode() const { } void Application::setIsInterstitialMode(bool interstitialMode) { - bool interstitialModeEnabled = Menu::getInstance()->isOptionChecked("Enable Interstitial"); + auto menu = Menu::getInstance(); + bool interstitialModeEnabled = menu->isOptionChecked("Enable Interstitial"); if (_interstitialMode != interstitialMode && interstitialModeEnabled) { _interstitialMode = interstitialMode; - qDebug() << "-------> interstitial mode changed: " << _interstitialMode << " ------------> "; + menu->setIsOptionChecked(MenuOption::Overlays, !_interstitialMode); emit interstitialModeChanged(_interstitialMode); } } diff --git a/scripts/system/interstitialPage.js b/scripts/system/interstitialPage.js index 87f415130f..dde3448b11 100644 --- a/scripts/system/interstitialPage.js +++ b/scripts/system/interstitialPage.js @@ -10,11 +10,11 @@ // /* global Script, Controller, Overlays, Quat, MyAvatar, Entities, print, Vec3, AddressManager, Render, Window, Toolbars, - Camera, HMD, location, Account*/ + Camera, HMD, location, Account, Xform*/ (function() { Script.include("/~/system/libraries/Xform.js"); - var DEBUG = true; + var DEBUG = false; var MAX_X_SIZE = 3.8; var EPSILON = 0.01; var isVisible = false; @@ -24,7 +24,6 @@ var sample = null; var MAX_LEFT_MARGIN = 1.9; var INNER_CIRCLE_WIDTH = 4.7; - var DESTINATION_CARD_Y_OFFSET = 2; var DEFAULT_Z_OFFSET = 5.45; var renderViewTask = Render.getConfig("RenderMainView"); @@ -83,7 +82,7 @@ }); - var domainName = "Test"; + var domainName = ""; var domainNameTextID = Overlays.addOverlay("text3d", { name: "Loading-Destination-Card-Text", localPosition: { x: 0.0, y: 0.8, z: 0.0 }, @@ -179,9 +178,7 @@ var TARGET_UPDATE_HZ = 60; // 50hz good enough, but we're using update var BASIC_TIMER_INTERVAL_MS = 1000 / TARGET_UPDATE_HZ; - var timerset = false; var lastInterval = Date.now(); - var timeElapsed = 0; var currentDomain = ""; var timer = null; var target = 0; @@ -206,16 +203,12 @@ return leftMargin; } - function resetValues() { - } - function lerp(a, b, t) { return ((1 - t) * a + t * b); } function startInterstitialPage() { if (timer === null) { - print("----------> starting <----------"); updateOverlays(Window.isPhysicsEnabled()); startAudio(); target = 0; @@ -255,7 +248,6 @@ uri: url }, function(error, data) { if (data.status === "success") { - print("-----------> settings domain description <----------"); var domainInfo = data.data; var domainDescriptionText = domainInfo.place.description; print("domainText: " + domainDescriptionText); @@ -346,44 +338,11 @@ Overlays.editOverlay(anchorOverlay, { localPosition: localPosition }); } - var progress = 0; - function updateProgress() { - print("updateProgress"); - var thisInterval = Date.now(); - var deltaTime = (thisInterval - lastInterval); - lastInterval = thisInterval; - timeElapsed += deltaTime; - - progress += (deltaTime / 1000); - if (progress > MAX_X_SIZE) { - progress = MAX_X_SIZE; - } - - var properties = { - localPosition: { x: (1.85 - (progress / 2) - (-0.029 * (progress / MAX_X_SIZE))), y: -0.935, z: 0.0 }, - dimensions: { - x: progress, - y: 2.8 - } - }; - - if (progress >= MAX_X_SIZE) { - progress = 0; - } - - Overlays.editOverlay(loadingBarProgress, properties); - - if (!toggle) { - Script.setTimeout(updateProgress, BASIC_TIMER_INTERVAL_MS); - } - } - function update() { var physicsEnabled = Window.isPhysicsEnabled(); var thisInterval = Date.now(); var deltaTime = (thisInterval - lastInterval); lastInterval = thisInterval; - timeElapsed += deltaTime; var nearbyEntitiesReadyCount = Window.getPhysicsNearbyEntitiesReadyCount(); var stabilityCount = Window.getPhysicsNearbyEntitiesStabilityCount(); @@ -407,16 +366,15 @@ } currentProgress = lerp(currentProgress, target, 0.2); var properties = { - localPosition: { x: (1.85 - (progress / 2) - (-0.029 * (progress / MAX_X_SIZE))), y: -0.935, z: 0.0 }, + localPosition: { x: (1.85 - (currentProgress / 2) - (-0.029 * (currentProgress / MAX_X_SIZE))), y: -0.935, z: 0.0 }, dimensions: { x: currentProgress, y: 2.8 } }; - print("progress: " + currentProgress); + Overlays.editOverlay(loadingBarProgress, properties); if ((physicsEnabled && (currentProgress >= (MAX_X_SIZE - EPSILON)))) { - print("----------> ending <--------"); updateOverlays((physicsEnabled || connectionToDomainFailed)); endAudio(); timer = null; @@ -431,7 +389,7 @@ Script.setTimeout(function() { print("location connected: " + location.isConnected); connectionToDomainFailed = !location.isConnected; - }, 300); + }, 1200); }); MyAvatar.sensorToWorldScaleChanged.connect(scaleInterstitialPage); @@ -444,10 +402,6 @@ button.clicked.connect(function() { toggle = !toggle; updateOverlays(toggle); - - if (!toggle) { - // Script.setTimeout(updateProgress, BASIC_TIMER_INTERVAL_MS); - } }); } From 05ff99a1d2f2f0aa8387bd505d665de26bc58519 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 9 Aug 2018 18:39:19 -0700 Subject: [PATCH 041/545] working on blendshapes --- interface/src/avatar/AvatarManager.cpp | 4 +- .../render-utils/src/CauterizedModel.cpp | 5 ++ .../render-utils/src/MeshPartPayload.cpp | 5 +- libraries/render-utils/src/Model.cpp | 54 +++++-------------- libraries/render-utils/src/Model.h | 2 +- 5 files changed, 26 insertions(+), 44 deletions(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index dbafd06611..efd1c103d9 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -353,15 +353,14 @@ void AvatarManager::simulateAvatarFades(float deltaTime) { QReadLocker locker(&_hashLock); QVector::iterator avatarItr = _avatarsToFade.begin(); const render::ScenePointer& scene = qApp->getMain3DScene(); + render::Transaction transaction; while (avatarItr != _avatarsToFade.end()) { auto avatar = std::static_pointer_cast(*avatarItr); avatar->updateFadingStatus(scene); if (!avatar->isFading()) { // fading to zero is such a rare event we push a unique transaction for each if (avatar->isInScene()) { - render::Transaction transaction; avatar->removeFromScene(*avatarItr, scene, transaction); - scene->enqueueTransaction(transaction); } avatarItr = _avatarsToFade.erase(avatarItr); } else { @@ -370,6 +369,7 @@ void AvatarManager::simulateAvatarFades(float deltaTime) { ++avatarItr; } } + scene->enqueueTransaction(transaction); } AvatarSharedPointer AvatarManager::newSharedAvatar() { diff --git a/libraries/render-utils/src/CauterizedModel.cpp b/libraries/render-utils/src/CauterizedModel.cpp index 80a9c5ccae..ba394b8b2f 100644 --- a/libraries/render-utils/src/CauterizedModel.cpp +++ b/libraries/render-utils/src/CauterizedModel.cpp @@ -75,6 +75,7 @@ void CauterizedModel::createRenderItemSet() { // Run through all of the meshes, and place them into their segregated, but unsorted buckets int shapeID = 0; + const FBXGeometry& fbxGeometry = getFBXGeometry(); uint32_t numMeshes = (uint32_t)meshes.size(); for (uint32_t i = 0; i < numMeshes; i++) { const auto& mesh = meshes.at(i); @@ -85,6 +86,10 @@ void CauterizedModel::createRenderItemSet() { // Create the render payloads int numParts = (int)mesh->getNumParts(); for (int partIndex = 0; partIndex < numParts; partIndex++) { + if (!fbxGeometry.meshes[i].blendshapes.empty()) { + _blendedVertexBuffers[i] = std::make_shared(); + _blendedVertexBuffers[i]->resize(fbxGeometry.meshes[i].vertices.size() * (sizeof(glm::vec3) + 2 * sizeof(NormalType))); + } auto ptr = std::make_shared(shared_from_this(), i, partIndex, shapeID, transform, offset); _modelMeshRenderItems << std::static_pointer_cast(ptr); auto material = getGeometry()->getShapeMaterial(shapeID); diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index ca6e736a65..58f4f170a0 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -208,7 +208,10 @@ ModelMeshPartPayload::ModelMeshPartPayload(ModelPointer model, int meshIndex, in bool useDualQuaternionSkinning = model->getUseDualQuaternionSkinning(); - _blendedVertexBuffer = model->_blendedVertexBuffers[_meshIndex]; + auto blendedVertexBuffer = model->_blendedVertexBuffers.find(_meshIndex); + if (blendedVertexBuffer != model->_blendedVertexBuffers.end()) { + _blendedVertexBuffer = blendedVertexBuffer->second; + } auto& modelMesh = model->getGeometry()->getMeshes().at(_meshIndex); const Model::MeshState& state = model->getMeshState(_meshIndex); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index ba0d714f7a..f92a6809f3 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -305,36 +305,6 @@ bool Model::updateGeometry() { state.clusterDualQuaternions.resize(mesh.clusters.size()); state.clusterMatrices.resize(mesh.clusters.size()); _meshStates.push_back(state); - - // Note: we add empty buffers for meshes that lack blendshapes so we can access the buffers by index - // later in ModelMeshPayload, however the vast majority of meshes will not have them. - // TODO? make _blendedVertexBuffers a map instead of vector and only add for meshes with blendshapes? - auto buffer = std::make_shared(); - if (!mesh.blendshapes.isEmpty()) { - std::vector normalsAndTangents; - normalsAndTangents.reserve(mesh.normals.size() + mesh.tangents.size()); - - for (auto normalIt = mesh.normals.begin(), tangentIt = mesh.tangents.begin(); - normalIt != mesh.normals.end(); - ++normalIt, ++tangentIt) { -#if FBX_PACK_NORMALS - glm::uint32 finalNormal; - glm::uint32 finalTangent; - buffer_helpers::packNormalAndTangent(*normalIt, *tangentIt, finalNormal, finalTangent); -#else - const auto finalNormal = *normalIt; - const auto finalTangent = *tangentIt; -#endif - normalsAndTangents.push_back(finalNormal); - normalsAndTangents.push_back(finalTangent); - } - - buffer->resize(mesh.vertices.size() * (sizeof(glm::vec3) + 2 * sizeof(NormalType))); - buffer->setSubData(0, mesh.vertices.size() * sizeof(glm::vec3), (const gpu::Byte*) mesh.vertices.constData()); - buffer->setSubData(mesh.vertices.size() * sizeof(glm::vec3), - mesh.normals.size() * 2 * sizeof(NormalType), (const gpu::Byte*) normalsAndTangents.data()); - } - _blendedVertexBuffers.push_back(buffer); } needFullUpdate = true; emit rigReady(); @@ -1280,9 +1250,9 @@ void Blender::run() { } // post the result to the geometry cache, which will dispatch to the model if still alive QMetaObject::invokeMethod(DependencyManager::get().data(), "setBlendedVertices", - Q_ARG(ModelPointer, _model), Q_ARG(int, _blendNumber), - Q_ARG(const Geometry::WeakPointer&, _geometry), Q_ARG(const QVector&, vertices), - Q_ARG(const QVector&, normals), Q_ARG(const QVector&, tangents)); + Q_ARG(ModelPointer, _model), Q_ARG(int, _blendNumber), + Q_ARG(const Geometry::WeakPointer&, _geometry), Q_ARG(const QVector&, vertices), + Q_ARG(const QVector&, normals), Q_ARG(const QVector&, tangents)); } void Model::setScaleToFit(bool scaleToFit, const glm::vec3& dimensions, bool forceRescale) { @@ -1463,7 +1433,7 @@ bool Model::maybeStartBlender() { void Model::setBlendedVertices(int blendNumber, const Geometry::WeakPointer& geometry, const QVector& vertices, const QVector& normals, const QVector& tangents) { auto geometryRef = geometry.lock(); - if (!geometryRef || _renderGeometry != geometryRef || _blendedVertexBuffers.empty() || blendNumber < _appliedBlendNumber) { + if (!geometryRef || _renderGeometry != geometryRef || blendNumber < _appliedBlendNumber) { return; } _appliedBlendNumber = blendNumber; @@ -1476,13 +1446,13 @@ void Model::setBlendedVertices(int blendNumber, const Geometry::WeakPointer& geo continue; } - gpu::BufferPointer& buffer = _blendedVertexBuffers[i]; + gpu::BufferPointer buffer = _blendedVertexBuffers[i]; const auto vertexCount = mesh.vertices.size(); const auto verticesSize = vertexCount * sizeof(glm::vec3); const auto offset = index * sizeof(glm::vec3); normalsAndTangents.clear(); - normalsAndTangents.resize(normals.size()+tangents.size()); + normalsAndTangents.resize(normals.size() + tangents.size()); // assert(normalsAndTangents.size() == 2 * vertexCount); // Interleave normals and tangents @@ -1510,7 +1480,7 @@ void Model::setBlendedVertices(int blendNumber, const Geometry::WeakPointer& geo } #else // Parallel version for performance - tbb::parallel_for(tbb::blocked_range(index, index+vertexCount), [&](const tbb::blocked_range& range) { + tbb::parallel_for(tbb::blocked_range(index, index + vertexCount), [&](const tbb::blocked_range& range) { auto normalsRange = std::make_pair(normals.begin() + range.begin(), normals.begin() + range.end()); auto tangentsRange = std::make_pair(tangents.begin() + range.begin(), tangents.begin() + range.end()); auto normalsAndTangentsIt = normalsAndTangents.begin() + (range.begin()-index)*2; @@ -1603,6 +1573,7 @@ void Model::createRenderItemSet() { // Run through all of the meshes, and place them into their segregated, but unsorted buckets int shapeID = 0; uint32_t numMeshes = (uint32_t)meshes.size(); + const FBXGeometry& fbxGeometry = getFBXGeometry(); for (uint32_t i = 0; i < numMeshes; i++) { const auto& mesh = meshes.at(i); if (!mesh) { @@ -1612,6 +1583,10 @@ void Model::createRenderItemSet() { // Create the render payloads int numParts = (int)mesh->getNumParts(); for (int partIndex = 0; partIndex < numParts; partIndex++) { + if (!fbxGeometry.meshes[i].blendshapes.empty()) { + _blendedVertexBuffers[i] = std::make_shared(); + _blendedVertexBuffers[i]->resize(fbxGeometry.meshes[i].vertices.size() * (sizeof(glm::vec3) + 2 * sizeof(NormalType))); + } _modelMeshRenderItems << std::make_shared(shared_from_this(), i, partIndex, shapeID, transform, offset); auto material = getGeometry()->getShapeMaterial(shapeID); _modelMeshMaterialNames.push_back(material ? material->getName() : ""); @@ -1724,8 +1699,8 @@ void ModelBlender::noteRequiresBlend(ModelPointer model) { } } -void ModelBlender::setBlendedVertices(ModelPointer model, int blendNumber, const Geometry::WeakPointer& geometry, - const QVector& vertices, const QVector& normals, +void ModelBlender::setBlendedVertices(ModelPointer model, int blendNumber, const Geometry::WeakPointer& geometry, + const QVector& vertices, const QVector& normals, const QVector& tangents) { if (model) { model->setBlendedVertices(blendNumber, geometry, vertices, normals, tangents); @@ -1744,4 +1719,3 @@ void ModelBlender::setBlendedVertices(ModelPointer model, int blendNumber, const } } } - diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 627e5fddab..1d0570f087 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -413,7 +413,7 @@ protected: QUrl _url; - gpu::Buffers _blendedVertexBuffers; + std::unordered_map _blendedVertexBuffers; QVector > > _dilatedTextures; From 94026fb4dda683a0af532fdc61e693201f2997f1 Mon Sep 17 00:00:00 2001 From: amantley Date: Mon, 20 Aug 2018 16:47:14 -0700 Subject: [PATCH 042/545] added activate(rotation) to prephysics update --- interface/src/avatar/MyAvatar.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 10e38afbe3..2a6cb0017a 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -3582,6 +3582,7 @@ void MyAvatar::FollowHelper::prePhysicsUpdate(MyAvatar& myAvatar, const glm::mat if (!isActive(Horizontal) && (shouldActivateHorizontalCG(myAvatar) || hasDriveInput)) { activate(Horizontal); if (myAvatar.getEnableStepResetRotation()) { + activate(Rotation); myAvatar.setHeadControllerFacingMovingAverage(myAvatar._headControllerFacing); } } @@ -3589,6 +3590,7 @@ void MyAvatar::FollowHelper::prePhysicsUpdate(MyAvatar& myAvatar, const glm::mat if (!isActive(Horizontal) && (shouldActivateHorizontal(myAvatar, desiredBodyMatrix, currentBodyMatrix) || hasDriveInput)) { activate(Horizontal); if (myAvatar.getEnableStepResetRotation()) { + activate(Rotation); myAvatar.setHeadControllerFacingMovingAverage(myAvatar._headControllerFacing); } } From 2dcdd607508eaa9dd98799915102913701a54cb3 Mon Sep 17 00:00:00 2001 From: amantley Date: Mon, 20 Aug 2018 17:32:52 -0700 Subject: [PATCH 043/545] added new AvatarConstants and more frequent horizontal recentering to deal with lurching walk in large tracked volumes --- interface/src/avatar/MyAvatar.cpp | 19 +++++++++++-------- libraries/shared/src/AvatarConstants.h | 2 +- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index d69ba21f6d..d1147cc796 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -3557,10 +3557,10 @@ static bool headAngularVelocityBelowThreshold(const controller::Pose& head) { return isBelowThreshold; } -static bool isWithinThresholdHeightMode(const controller::Pose& head,const float& newMode) { +static bool isWithinThresholdHeightMode(const controller::Pose& head, const float& newMode, const float& scale) { bool isWithinThreshold = true; if (head.isValid()) { - isWithinThreshold = (head.getTranslation().y - newMode) > DEFAULT_AVATAR_MODE_HEIGHT_STEPPING_THRESHOLD; + isWithinThreshold = (head.getTranslation().y - newMode) > DEFAULT_AVATAR_MODE_HEIGHT_STEPPING_THRESHOLD * scale; } return isWithinThreshold; } @@ -3791,8 +3791,7 @@ void MyAvatar::lateUpdatePalms() { Avatar::updatePalms(); } - -static const float FOLLOW_TIME = 0.5f; +static const float FOLLOW_TIME = 0.1f; MyAvatar::FollowHelper::FollowHelper() { deactivate(); @@ -3883,9 +3882,10 @@ bool MyAvatar::FollowHelper::shouldActivateHorizontalCG(MyAvatar& myAvatar) cons controller::Pose currentRightHandPose = myAvatar.getControllerPoseInAvatarFrame(controller::Action::RIGHT_HAND); bool stepDetected = false; + float myScale = myAvatar.getAvatarScale(); if (!withinBaseOfSupport(currentHeadPose) && headAngularVelocityBelowThreshold(currentHeadPose) && - isWithinThresholdHeightMode(currentHeadPose, myAvatar.getCurrentStandingHeight()) && + isWithinThresholdHeightMode(currentHeadPose, myAvatar.getCurrentStandingHeight(), myScale) && handDirectionMatchesHeadDirection(currentLeftHandPose, currentRightHandPose, currentHeadPose) && handAngularVelocityBelowThreshold(currentLeftHandPose, currentRightHandPose) && headVelocityGreaterThanThreshold(currentHeadPose) && @@ -3897,8 +3897,8 @@ bool MyAvatar::FollowHelper::shouldActivateHorizontalCG(MyAvatar& myAvatar) cons glm::vec3 defaultHeadPosition = myAvatar.getAbsoluteDefaultJointTranslationInObjectFrame(myAvatar.getJointIndex("Head")); glm::vec3 currentHeadPosition = currentHeadPose.getTranslation(); float anatomicalHeadToHipsDistance = glm::length(defaultHeadPosition - defaultHipsPosition); - if (!isActive(Horizontal) && - (glm::length(currentHeadPosition - defaultHipsPosition) > (anatomicalHeadToHipsDistance + DEFAULT_AVATAR_SPINE_STRETCH_LIMIT))) { + if (!isActive(Horizontal) && + (glm::length(currentHeadPosition - defaultHipsPosition) > (anatomicalHeadToHipsDistance + (DEFAULT_AVATAR_SPINE_STRETCH_LIMIT * anatomicalHeadToHipsDistance * myAvatar.getAvatarScale())))) { myAvatar.setResetMode(true); stepDetected = true; } @@ -3918,6 +3918,9 @@ bool MyAvatar::FollowHelper::shouldActivateVertical(const MyAvatar& myAvatar, co void MyAvatar::FollowHelper::prePhysicsUpdate(MyAvatar& myAvatar, const glm::mat4& desiredBodyMatrix, const glm::mat4& currentBodyMatrix, bool hasDriveInput) { + const float VELOCITY_THRESHHOLD = 0.5f; + float currentVelocity = glm::length(myAvatar.getLocalVelocity() / myAvatar.getSensorToWorldScale()); + if (myAvatar.getHMDLeanRecenterEnabled() && qApp->getCamera().getMode() != CAMERA_MODE_MIRROR) { if (!isActive(Rotation) && (shouldActivateRotation(myAvatar, desiredBodyMatrix, currentBodyMatrix) || hasDriveInput)) { @@ -3925,7 +3928,7 @@ void MyAvatar::FollowHelper::prePhysicsUpdate(MyAvatar& myAvatar, const glm::mat myAvatar.setHeadControllerFacingMovingAverage(myAvatar._headControllerFacing); } if (myAvatar.getCenterOfGravityModelEnabled()) { - if (!isActive(Horizontal) && (shouldActivateHorizontalCG(myAvatar) || hasDriveInput)) { + if ((!isActive(Horizontal) && (shouldActivateHorizontalCG(myAvatar) || hasDriveInput)) || ( isActive(Horizontal) && (currentVelocity > VELOCITY_THRESHHOLD))) { activate(Horizontal); } } else { diff --git a/libraries/shared/src/AvatarConstants.h b/libraries/shared/src/AvatarConstants.h index cdc571d1aa..c3e8a3f173 100644 --- a/libraries/shared/src/AvatarConstants.h +++ b/libraries/shared/src/AvatarConstants.h @@ -34,7 +34,7 @@ const float DEFAULT_HANDS_ANGULAR_VELOCITY_STEPPING_THRESHOLD = 3.3f; const float DEFAULT_HEAD_VELOCITY_STEPPING_THRESHOLD = 0.18f; const float DEFAULT_HEAD_PITCH_STEPPING_TOLERANCE = 7.0f; const float DEFAULT_HEAD_ROLL_STEPPING_TOLERANCE = 7.0f; -const float DEFAULT_AVATAR_SPINE_STRETCH_LIMIT = 0.03f; +const float DEFAULT_AVATAR_SPINE_STRETCH_LIMIT = 0.04f; const float DEFAULT_AVATAR_FORWARD_DAMPENING_FACTOR = 0.5f; const float DEFAULT_AVATAR_LATERAL_DAMPENING_FACTOR = 2.0f; const float DEFAULT_AVATAR_HIPS_MASS = 40.0f; From 1e2ca579c776287652c60399ab0703539cc4a85e Mon Sep 17 00:00:00 2001 From: amantley Date: Mon, 20 Aug 2018 18:06:34 -0700 Subject: [PATCH 044/545] widened base of support and put head angular and hand angular back to normal --- libraries/shared/src/AvatarConstants.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/shared/src/AvatarConstants.h b/libraries/shared/src/AvatarConstants.h index c3e8a3f173..4e6fa67c9f 100644 --- a/libraries/shared/src/AvatarConstants.h +++ b/libraries/shared/src/AvatarConstants.h @@ -24,10 +24,10 @@ const float DEFAULT_AVATAR_SUPPORT_BASE_LEFT = -0.25f; const float DEFAULT_AVATAR_SUPPORT_BASE_RIGHT = 0.25f; const float DEFAULT_AVATAR_SUPPORT_BASE_FRONT = -0.20f; const float DEFAULT_AVATAR_SUPPORT_BASE_BACK = 0.12f; -const float DEFAULT_AVATAR_LATERAL_STEPPING_THRESHOLD = 0.10f; -const float DEFAULT_AVATAR_ANTERIOR_STEPPING_THRESHOLD = 0.04f; -const float DEFAULT_AVATAR_POSTERIOR_STEPPING_THRESHOLD = 0.05f; -const float DEFAULT_AVATAR_HEAD_ANGULAR_VELOCITY_STEPPING_THRESHOLD = 0.3f; +const float DEFAULT_AVATAR_LATERAL_STEPPING_THRESHOLD = 0.15f; +const float DEFAULT_AVATAR_ANTERIOR_STEPPING_THRESHOLD = 0.07f; +const float DEFAULT_AVATAR_POSTERIOR_STEPPING_THRESHOLD = 0.08f; +const float DEFAULT_AVATAR_HEAD_ANGULAR_VELOCITY_STEPPING_THRESHOLD = 0.6f; const float DEFAULT_AVATAR_MODE_HEIGHT_STEPPING_THRESHOLD = -0.02f; const float DEFAULT_HANDS_VELOCITY_DIRECTION_STEPPING_THRESHOLD = 0.4f; const float DEFAULT_HANDS_ANGULAR_VELOCITY_STEPPING_THRESHOLD = 3.3f; From a378435683b2bf9c5130ade161a29caa8f4d21ab Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 21 Aug 2018 10:20:51 -0700 Subject: [PATCH 045/545] Fix MS16003: In PAL/GoTo WebView, 'BACK' closes app when you can't go back --- interface/resources/qml/controls/TabletWebView.qml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/controls/TabletWebView.qml b/interface/resources/qml/controls/TabletWebView.qml index bc958aa876..db695dbfb2 100644 --- a/interface/resources/qml/controls/TabletWebView.qml +++ b/interface/resources/qml/controls/TabletWebView.qml @@ -52,12 +52,18 @@ Item { id: back enabledColor: hifi.colors.darkGray disabledColor: hifi.colors.lightGrayText - enabled: historyIndex > 0 + enabled: true text: "BACK" MouseArea { anchors.fill: parent - onClicked: goBack() + onClicked: { + if (historyIndex > 0) { + goBack(); + } else { + closeWebEngine(); + } + } } } From b2fb2c7f9832c529d8c1530f5b350e80db5a31e7 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Tue, 21 Aug 2018 10:45:59 -0700 Subject: [PATCH 046/545] fix build error --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index afad67b43e..9d5a7a01f8 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1373,7 +1373,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo }); connect(this, &Application::activeDisplayPluginChanged, reinterpret_cast(audioScriptingInterface.data()), &scripting::Audio::onContextChanged); - connect(this, &Application::interstitialModeChanged, audioIO.data(), &AudioClient::setInterstitialStatus); + connect(this, &Application::interstitialModeChanged, audioIO, &AudioClient::setInterstitialStatus); } // Create the rendering engine. This can be slow on some machines due to lots of From bfb9b679687ae4a0e4a5dac2e167b162d5101cd1 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Tue, 21 Aug 2018 11:17:33 -0700 Subject: [PATCH 047/545] more debug statements --- interface/resources/qml/hifi/tablet/TabletHome.qml | 6 ++++++ scripts/system/menu.js | 1 + scripts/system/tablet-ui/tabletUI.js | 6 +++--- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/interface/resources/qml/hifi/tablet/TabletHome.qml b/interface/resources/qml/hifi/tablet/TabletHome.qml index 1922b02f93..10a9f01337 100644 --- a/interface/resources/qml/hifi/tablet/TabletHome.qml +++ b/interface/resources/qml/hifi/tablet/TabletHome.qml @@ -117,6 +117,7 @@ Item { id: pageRepeater model: Math.ceil(tabletProxy.buttons.rowCount() / TabletEnums.ButtonsOnPage) onItemAdded: { + console.log("onItemAdded: " + tabletProxy.buttons.rowCount()); item.proxyModel.sourceModel = tabletProxy.buttons; item.proxyModel.pageIndex = index; } @@ -208,6 +209,7 @@ Item { Component.onCompleted: updateProperties() function updateProperties() { + console.log("updateProperties: " + tabletProxy.buttons.rowCount()); var keys = Object.keys(modelData.properties).forEach(function (key) { if (tabletButton[key] !== modelData.properties[key]) { tabletButton[key] = modelData.properties[key]; @@ -269,6 +271,10 @@ Item { anchors.bottom: parent.bottom anchors.horizontalCenter: parent.horizontalCenter count: swipeView.count + + Component.onCompleted: { + console.log("pageIndicator: " + pageIndicator.count); + } } } diff --git a/scripts/system/menu.js b/scripts/system/menu.js index d669d3d918..1db210216a 100644 --- a/scripts/system/menu.js +++ b/scripts/system/menu.js @@ -52,6 +52,7 @@ var HOME_BUTTON_TEXTURE = "http://hifi-content.s3.amazonaws.com/alan/dev/tablet- if (isHMDMode) { button = tablet.addButton(buttonProperties); button.clicked.connect(onClicked); + print("Adding menu button"); } else if (button) { button.clicked.disconnect(onClicked); tablet.removeButton(button); diff --git a/scripts/system/tablet-ui/tabletUI.js b/scripts/system/tablet-ui/tabletUI.js index f339475f72..c28040000b 100644 --- a/scripts/system/tablet-ui/tabletUI.js +++ b/scripts/system/tablet-ui/tabletUI.js @@ -22,7 +22,7 @@ var DEFAULT_TABLET_SCALE = 70; var preMakeTime = Date.now(); var validCheckTime = Date.now(); - var debugTablet = false; + var debugTablet = true; var tabletScalePercentage = 70.0; var UIWebTablet = null; var MSECS_PER_SEC = 1000.0; @@ -298,7 +298,7 @@ } wantsMenu = clicked; }); - + clickMapping.from(Controller.Standard.LeftSecondaryThumb).peek().to(function (clicked) { if (clicked) { //activeHudPoint2d(Controller.Standard.LeftHand); @@ -306,7 +306,7 @@ } wantsMenu = clicked; }); - + clickMapping.from(Controller.Standard.Start).peek().to(function (clicked) { if (clicked) { //activeHudPoint2dGamePad(); From 1fabc77244d2546979e0ed5d95979714b89fc481 Mon Sep 17 00:00:00 2001 From: amantley Date: Tue, 21 Aug 2018 12:34:05 -0700 Subject: [PATCH 048/545] latest update to stop lurching, and allow leaning, and stop perma leans --- interface/src/avatar/MyAvatar.cpp | 9 ++++++--- libraries/shared/src/AvatarConstants.h | 8 ++++---- scripts/developer/objectOrientedStep.js | 7 ++++++- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index d1147cc796..ba4636bfa6 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -3560,7 +3560,7 @@ static bool headAngularVelocityBelowThreshold(const controller::Pose& head) { static bool isWithinThresholdHeightMode(const controller::Pose& head, const float& newMode, const float& scale) { bool isWithinThreshold = true; if (head.isValid()) { - isWithinThreshold = (head.getTranslation().y - newMode) > DEFAULT_AVATAR_MODE_HEIGHT_STEPPING_THRESHOLD * scale; + isWithinThreshold = (head.getTranslation().y - newMode) > (DEFAULT_AVATAR_MODE_HEIGHT_STEPPING_THRESHOLD * scale); } return isWithinThreshold; } @@ -3881,6 +3881,7 @@ bool MyAvatar::FollowHelper::shouldActivateHorizontalCG(MyAvatar& myAvatar) cons controller::Pose currentLeftHandPose = myAvatar.getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND); controller::Pose currentRightHandPose = myAvatar.getControllerPoseInAvatarFrame(controller::Action::RIGHT_HAND); + bool stepDetected = false; float myScale = myAvatar.getAvatarScale(); if (!withinBaseOfSupport(currentHeadPose) && @@ -3898,10 +3899,12 @@ bool MyAvatar::FollowHelper::shouldActivateHorizontalCG(MyAvatar& myAvatar) cons glm::vec3 currentHeadPosition = currentHeadPose.getTranslation(); float anatomicalHeadToHipsDistance = glm::length(defaultHeadPosition - defaultHipsPosition); if (!isActive(Horizontal) && - (glm::length(currentHeadPosition - defaultHipsPosition) > (anatomicalHeadToHipsDistance + (DEFAULT_AVATAR_SPINE_STRETCH_LIMIT * anatomicalHeadToHipsDistance * myAvatar.getAvatarScale())))) { + (glm::length(currentHeadPosition - defaultHipsPosition) > (anatomicalHeadToHipsDistance + (DEFAULT_AVATAR_SPINE_STRETCH_LIMIT * anatomicalHeadToHipsDistance)))) { myAvatar.setResetMode(true); + qCDebug(interfaceapp) << "failsafe called, default back " << anatomicalHeadToHipsDistance << " scale " << myAvatar.getAvatarScale() << " current length " << glm::length(currentHeadPosition - defaultHipsPosition); stepDetected = true; } + qCDebug(interfaceapp) << "current head height " << currentHeadPose.getTranslation().y << " scale " << myAvatar.getAvatarScale() << " anatomical " << anatomicalHeadToHipsDistance; } return stepDetected; } @@ -3918,7 +3921,7 @@ bool MyAvatar::FollowHelper::shouldActivateVertical(const MyAvatar& myAvatar, co void MyAvatar::FollowHelper::prePhysicsUpdate(MyAvatar& myAvatar, const glm::mat4& desiredBodyMatrix, const glm::mat4& currentBodyMatrix, bool hasDriveInput) { - const float VELOCITY_THRESHHOLD = 0.5f; + const float VELOCITY_THRESHHOLD = 1.0f; float currentVelocity = glm::length(myAvatar.getLocalVelocity() / myAvatar.getSensorToWorldScale()); if (myAvatar.getHMDLeanRecenterEnabled() && diff --git a/libraries/shared/src/AvatarConstants.h b/libraries/shared/src/AvatarConstants.h index 4e6fa67c9f..6f807a4115 100644 --- a/libraries/shared/src/AvatarConstants.h +++ b/libraries/shared/src/AvatarConstants.h @@ -24,17 +24,17 @@ const float DEFAULT_AVATAR_SUPPORT_BASE_LEFT = -0.25f; const float DEFAULT_AVATAR_SUPPORT_BASE_RIGHT = 0.25f; const float DEFAULT_AVATAR_SUPPORT_BASE_FRONT = -0.20f; const float DEFAULT_AVATAR_SUPPORT_BASE_BACK = 0.12f; -const float DEFAULT_AVATAR_LATERAL_STEPPING_THRESHOLD = 0.15f; +const float DEFAULT_AVATAR_LATERAL_STEPPING_THRESHOLD = 0.10f; const float DEFAULT_AVATAR_ANTERIOR_STEPPING_THRESHOLD = 0.07f; -const float DEFAULT_AVATAR_POSTERIOR_STEPPING_THRESHOLD = 0.08f; -const float DEFAULT_AVATAR_HEAD_ANGULAR_VELOCITY_STEPPING_THRESHOLD = 0.6f; +const float DEFAULT_AVATAR_POSTERIOR_STEPPING_THRESHOLD = 0.06f; +const float DEFAULT_AVATAR_HEAD_ANGULAR_VELOCITY_STEPPING_THRESHOLD = 0.4f; const float DEFAULT_AVATAR_MODE_HEIGHT_STEPPING_THRESHOLD = -0.02f; const float DEFAULT_HANDS_VELOCITY_DIRECTION_STEPPING_THRESHOLD = 0.4f; const float DEFAULT_HANDS_ANGULAR_VELOCITY_STEPPING_THRESHOLD = 3.3f; const float DEFAULT_HEAD_VELOCITY_STEPPING_THRESHOLD = 0.18f; const float DEFAULT_HEAD_PITCH_STEPPING_TOLERANCE = 7.0f; const float DEFAULT_HEAD_ROLL_STEPPING_TOLERANCE = 7.0f; -const float DEFAULT_AVATAR_SPINE_STRETCH_LIMIT = 0.04f; +const float DEFAULT_AVATAR_SPINE_STRETCH_LIMIT = 0.05f; const float DEFAULT_AVATAR_FORWARD_DAMPENING_FACTOR = 0.5f; const float DEFAULT_AVATAR_LATERAL_DAMPENING_FACTOR = 2.0f; const float DEFAULT_AVATAR_HIPS_MASS = 40.0f; diff --git a/scripts/developer/objectOrientedStep.js b/scripts/developer/objectOrientedStep.js index 4eca1fb115..a5c27e36b9 100644 --- a/scripts/developer/objectOrientedStep.js +++ b/scripts/developer/objectOrientedStep.js @@ -584,7 +584,11 @@ function update(dt) { // make the signal colors reflect the current thresholds that have been crossed updateSignalColors(); - print("the current back length is " + currentStateReadings.backLength + " " + DEFAULT_TORSO_LENGTH); + + SPINE_STRETCH_LIMIT = (0.04) * DEFAULT_TORSO_LENGTH * MyAvatar.scale; + + //print("the spine stretch limit is " + SPINE_STRETCH_LIMIT + " head avatar space is " + currentStateReadings.headPose.translation.y); + //print("the current back length is " + currentStateReadings.backLength + " " + DEFAULT_TORSO_LENGTH); // Conditions for taking a step. // 1. off the base of support. front, lateral, back edges. // 2. head is not lower than the height mode value by more than the maxHeightChange tolerance @@ -672,6 +676,7 @@ Script.setTimeout(function() { DEFAULT_HIPS_POSITION = MyAvatar.getAbsoluteDefaultJointTranslationInObjectFrame(MyAvatar.getJointIndex("Hips")); DEFAULT_HEAD_POSITION = MyAvatar.getAbsoluteDefaultJointTranslationInObjectFrame(MyAvatar.getJointIndex("Head")); DEFAULT_TORSO_LENGTH = Vec3.length(Vec3.subtract(DEFAULT_HEAD_POSITION, DEFAULT_HIPS_POSITION)); + SPINE_STRETCH_LIMIT = (0.04) * DEFAULT_TORSO_LENGTH * MyAvatar.scale; },(4*LOADING_DELAY)); Script.update.connect(update); From af5c7a7a674618f16d20f69ccf980c9c2476d63c Mon Sep 17 00:00:00 2001 From: Cristian Luis Duarte Date: Tue, 21 Aug 2018 16:35:47 -0300 Subject: [PATCH 049/545] Android - Domains List - cache in memory only on this instance (deleted if app restarts) allows for fast list display. Showing again also asks for update so in some seconds the list gets updated in case of changes --- .../hifiinterface/fragment/HomeFragment.java | 25 ++++++++---- .../hifiinterface/view/DomainAdapter.java | 38 +++++++++++++++---- 2 files changed, 47 insertions(+), 16 deletions(-) diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/HomeFragment.java b/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/HomeFragment.java index 7bd373cf1d..86b8625cfe 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/HomeFragment.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/HomeFragment.java @@ -76,18 +76,22 @@ public class HomeFragment extends Fragment { }); mDomainAdapter.setListener(new DomainAdapter.AdapterListener() { @Override - public void onEmptyAdapter() { + public void onEmptyAdapter(boolean shouldStopRefreshing) { searchNoResultsView.setText(R.string.search_no_results); searchNoResultsView.setVisibility(View.VISIBLE); mDomainsView.setVisibility(View.GONE); - mSwipeRefreshLayout.setRefreshing(false); + if (shouldStopRefreshing) { + mSwipeRefreshLayout.setRefreshing(false); + } } @Override - public void onNonEmptyAdapter() { + public void onNonEmptyAdapter(boolean shouldStopRefreshing) { searchNoResultsView.setVisibility(View.GONE); mDomainsView.setVisibility(View.VISIBLE); - mSwipeRefreshLayout.setRefreshing(false); + if (shouldStopRefreshing) { + mSwipeRefreshLayout.setRefreshing(false); + } } @Override @@ -96,11 +100,20 @@ public class HomeFragment extends Fragment { } }); mDomainsView.setAdapter(mDomainAdapter); + mDomainAdapter.startLoad(); mSearchView = rootView.findViewById(R.id.searchView); mSearchIconView = rootView.findViewById(R.id.search_mag_icon); mClearSearch = rootView.findViewById(R.id.search_clear); + getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); + + return rootView; + } + + @Override + public void onStart() { + super.onStart(); mSearchView.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {} @@ -142,10 +155,6 @@ public class HomeFragment extends Fragment { mDomainAdapter.loadDomains(mSearchView.getText().toString(), true); } }); - - getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); - - return rootView; } @Override diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/view/DomainAdapter.java b/android/app/src/main/java/io/highfidelity/hifiinterface/view/DomainAdapter.java index 71d634e9ea..6860742a0d 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/view/DomainAdapter.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/view/DomainAdapter.java @@ -12,6 +12,7 @@ import android.widget.TextView; import com.squareup.picasso.Picasso; +import java.util.Arrays; import java.util.List; import io.highfidelity.hifiinterface.R; @@ -36,19 +37,39 @@ public class DomainAdapter extends RecyclerView.Adapter 0) { + mDomains = Arrays.copyOf(DOMAINS_TMP_CACHE, DOMAINS_TMP_CACHE.length); + notifyDataSetChanged(); + if (mAdapterListener != null) { + if (mDomains.length == 0) { + mAdapterListener.onEmptyAdapter(false); + } else { + mAdapterListener.onNonEmptyAdapter(false); + } + } + } + } + public void loadDomains(String filterText, boolean forceRefresh) { domainProvider.retrieve(filterText, new DomainProvider.DomainCallback() { @Override @@ -60,13 +81,16 @@ public class DomainAdapter extends RecyclerView.Adapter Date: Tue, 21 Aug 2018 17:47:40 -0300 Subject: [PATCH 050/545] Android - People List - cache in memory only on this instance (deleted if app restarts) allows for fast list display. Showing again also asks for update so in some ms the list gets updated in case of changes --- .../fragment/FriendsFragment.java | 14 +++++--- .../hifiinterface/view/UserListAdapter.java | 35 ++++++++++++++++--- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/FriendsFragment.java b/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/FriendsFragment.java index 2a008d7950..2475c4d887 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/FriendsFragment.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/FriendsFragment.java @@ -98,13 +98,17 @@ public class FriendsFragment extends Fragment { mUsersAdapter.setListener(new UserListAdapter.AdapterListener() { @Override - public void onEmptyAdapter() { - mSwipeRefreshLayout.setRefreshing(false); + public void onEmptyAdapter(boolean shouldStopRefreshing) { + if (shouldStopRefreshing) { + mSwipeRefreshLayout.setRefreshing(false); + } } @Override - public void onNonEmptyAdapter() { - mSwipeRefreshLayout.setRefreshing(false); + public void onNonEmptyAdapter(boolean shouldStopRefreshing) { + if (shouldStopRefreshing) { + mSwipeRefreshLayout.setRefreshing(false); + } } @Override @@ -115,6 +119,8 @@ public class FriendsFragment extends Fragment { mUsersView.setAdapter(mUsersAdapter); + mUsersAdapter.startLoad(); + mSlidingUpPanelLayout.setFadeOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/view/UserListAdapter.java b/android/app/src/main/java/io/highfidelity/hifiinterface/view/UserListAdapter.java index 9f62b21250..a34de5b34e 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/view/UserListAdapter.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/view/UserListAdapter.java @@ -37,28 +37,53 @@ public class UserListAdapter extends RecyclerView.Adapter USERS_TMP_CACHE; + public UserListAdapter(Context c, UsersProvider usersProvider) { mContext = c; mInflater = LayoutInflater.from(mContext); mProvider = usersProvider; - loadUsers(); } public void setListener(AdapterListener adapterListener) { mAdapterListener = adapterListener; } + public void startLoad() { + useTmpCachedUsers(); + loadUsers(); + } + + private void useTmpCachedUsers() { + if (USERS_TMP_CACHE != null && USERS_TMP_CACHE.size() > 0) { + mUsers = new ArrayList<>(USERS_TMP_CACHE.size()); + mUsers.addAll(USERS_TMP_CACHE); + notifyDataSetChanged(); + if (mAdapterListener != null) { + if (mUsers.isEmpty()) { + mAdapterListener.onEmptyAdapter(false); + } else { + mAdapterListener.onNonEmptyAdapter(false); + } + } + } + } + public void loadUsers() { mProvider.retrieve(new UsersProvider.UsersCallback() { @Override public void retrieveOk(List users) { mUsers = new ArrayList<>(users); notifyDataSetChanged(); + + USERS_TMP_CACHE = new ArrayList<>(mUsers.size()); + USERS_TMP_CACHE.addAll(mUsers); + if (mAdapterListener != null) { if (mUsers.isEmpty()) { - mAdapterListener.onEmptyAdapter(); + mAdapterListener.onEmptyAdapter(true); } else { - mAdapterListener.onNonEmptyAdapter(); + mAdapterListener.onNonEmptyAdapter(true); } } } @@ -240,8 +265,8 @@ public class UserListAdapter extends RecyclerView.Adapter Date: Tue, 21 Aug 2018 14:04:29 -0700 Subject: [PATCH 051/545] adding fix --- .../controllers/controllerModules/webSurfaceLaserInput.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js b/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js index ef9ff0c6ae..4077d07c38 100644 --- a/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js +++ b/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js @@ -76,7 +76,7 @@ Script.include("/~/system/libraries/controllers.js"); var objectID = intersection.objectID; if (intersection.type === Picks.INTERSECTED_OVERLAY) { if ((HMD.tabletID && objectID === HMD.tabletID) || - (HMD.tabletScreenID && objectID === HMD.tabletScreenID) || + (HMD.tabletScreenID && objectID === HMD.tabletScreenID) || (HMD.homeButtonID && objectID === HMD.homeButtonID)) { return true; } else { @@ -122,9 +122,9 @@ Script.include("/~/system/libraries/controllers.js"); var isTriggerPressed = controllerData.triggerValues[this.hand] > TRIGGER_OFF_VALUE && controllerData.triggerValues[this.otherHand] <= TRIGGER_OFF_VALUE; var allowThisModule = !otherModuleRunning || isTriggerPressed; + if (allowThisModule && this.isPointingAtTriggerable(controllerData, isTriggerPressed) && !this.isPointingAtNearGrabbableEntity(controllerData, isTriggerPressed)) { - //(controllerData.nearbyEntityProperties[this.hand] !== [])) { this.updateAllwaysOn(); if (isTriggerPressed) { this.dominantHandOverride = true; // Override dominant hand. @@ -147,7 +147,6 @@ Script.include("/~/system/libraries/controllers.js"); var laserOn = isTriggerPressed || this.parameters.handLaser.allwaysOn; if (allowThisModule && (laserOn && this.isPointingAtTriggerable(controllerData, isTriggerPressed)) && !this.isPointingAtNearGrabbableEntity(controllerData, isTriggerPressed)) { - //(controllerData.nearbyEntityProperties[this.hand] !== [])) { this.running = true; return makeRunningValues(true, [], []); } From 7360629d31b452e295ead23e38b9f46fbf231a30 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Tue, 21 Aug 2018 14:13:55 -0700 Subject: [PATCH 052/545] modifying variable naming to fit convention --- .../controllers/controllerModules/webSurfaceLaserInput.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js b/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js index 4077d07c38..de3eb26086 100644 --- a/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js +++ b/scripts/system/controllers/controllerModules/webSurfaceLaserInput.js @@ -84,9 +84,9 @@ Script.include("/~/system/libraries/controllers.js"); return overlayType === "web3d" || triggerPressed; } } else if (intersection.type === Picks.INTERSECTED_ENTITY) { - var entityProperty = Entities.getEntityProperties(objectID); - var entityType = entityProperty.type; - var isLocked = entityProperty.locked; + var entityProperties = Entities.getEntityProperties(objectID); + var entityType = entityProperties.type; + var isLocked = entityProperties.locked; return entityType === "Web" && (!isLocked || triggerPressed); } return false; From 4227df30e6bfd93b438293ea970c3f8cca1b69e5 Mon Sep 17 00:00:00 2001 From: Cristian Luis Duarte Date: Tue, 21 Aug 2018 18:40:10 -0300 Subject: [PATCH 053/545] Android - People and Domain list - synchronize cache and request code --- .../hifiinterface/view/DomainAdapter.java | 40 ++++++++++--------- .../hifiinterface/view/UserListAdapter.java | 37 +++++++++-------- 2 files changed, 43 insertions(+), 34 deletions(-) diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/view/DomainAdapter.java b/android/app/src/main/java/io/highfidelity/hifiinterface/view/DomainAdapter.java index 6860742a0d..78251ac4a4 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/view/DomainAdapter.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/view/DomainAdapter.java @@ -57,14 +57,16 @@ public class DomainAdapter extends RecyclerView.Adapter 0) { - mDomains = Arrays.copyOf(DOMAINS_TMP_CACHE, DOMAINS_TMP_CACHE.length); - notifyDataSetChanged(); - if (mAdapterListener != null) { - if (mDomains.length == 0) { - mAdapterListener.onEmptyAdapter(false); - } else { - mAdapterListener.onNonEmptyAdapter(false); + synchronized (this) { + if (DOMAINS_TMP_CACHE != null && DOMAINS_TMP_CACHE.length > 0) { + mDomains = Arrays.copyOf(DOMAINS_TMP_CACHE, DOMAINS_TMP_CACHE.length); + notifyDataSetChanged(); + if (mAdapterListener != null) { + if (mDomains.length == 0) { + mAdapterListener.onEmptyAdapter(false); + } else { + mAdapterListener.onNonEmptyAdapter(false); + } } } } @@ -81,16 +83,18 @@ public class DomainAdapter extends RecyclerView.Adapter 0) { - mUsers = new ArrayList<>(USERS_TMP_CACHE.size()); - mUsers.addAll(USERS_TMP_CACHE); - notifyDataSetChanged(); - if (mAdapterListener != null) { - if (mUsers.isEmpty()) { - mAdapterListener.onEmptyAdapter(false); - } else { - mAdapterListener.onNonEmptyAdapter(false); + synchronized (this) { + if (USERS_TMP_CACHE != null && USERS_TMP_CACHE.size() > 0) { + mUsers = new ArrayList<>(USERS_TMP_CACHE.size()); + mUsers.addAll(USERS_TMP_CACHE); + notifyDataSetChanged(); + if (mAdapterListener != null) { + if (mUsers.isEmpty()) { + mAdapterListener.onEmptyAdapter(false); + } else { + mAdapterListener.onNonEmptyAdapter(false); + } } } } @@ -76,14 +78,16 @@ public class UserListAdapter extends RecyclerView.Adapter(users); notifyDataSetChanged(); - USERS_TMP_CACHE = new ArrayList<>(mUsers.size()); - USERS_TMP_CACHE.addAll(mUsers); + synchronized (this) { + USERS_TMP_CACHE = new ArrayList<>(mUsers.size()); + USERS_TMP_CACHE.addAll(mUsers); - if (mAdapterListener != null) { - if (mUsers.isEmpty()) { - mAdapterListener.onEmptyAdapter(true); - } else { - mAdapterListener.onNonEmptyAdapter(true); + if (mAdapterListener != null) { + if (mUsers.isEmpty()) { + mAdapterListener.onEmptyAdapter(true); + } else { + mAdapterListener.onNonEmptyAdapter(true); + } } } } @@ -269,4 +273,5 @@ public class UserListAdapter extends RecyclerView.Adapter Date: Tue, 21 Aug 2018 14:44:55 -0700 Subject: [PATCH 054/545] Split readPendingDatagrams() into two slots --- libraries/networking/src/udt/Socket.cpp | 67 ++++++++++++++++++------- libraries/networking/src/udt/Socket.h | 14 ++++++ 2 files changed, 62 insertions(+), 19 deletions(-) diff --git a/libraries/networking/src/udt/Socket.cpp b/libraries/networking/src/udt/Socket.cpp index c378987cd0..d01b937b8b 100644 --- a/libraries/networking/src/udt/Socket.cpp +++ b/libraries/networking/src/udt/Socket.cpp @@ -37,6 +37,7 @@ Socket::Socket(QObject* parent, bool shouldChangeSocketOptions) : _shouldChangeSocketOptions(shouldChangeSocketOptions) { connect(&_udpSocket, &QUdpSocket::readyRead, this, &Socket::readPendingDatagrams); + connect(this, &Socket::pendingDatagrams, this, &Socket::processPendingDatagrams); // make sure we hear about errors and state changes from the underlying socket connect(&_udpSocket, SIGNAL(error(QAbstractSocket::SocketError)), @@ -315,55 +316,80 @@ void Socket::checkForReadyReadBackup() { } void Socket::readPendingDatagrams() { + int packetsRead = 0; + int packetSizeWithHeader = -1; - while (_udpSocket.hasPendingDatagrams() && (packetSizeWithHeader = _udpSocket.pendingDatagramSize()) != -1) { - - // we're reading a packet so re-start the readyRead backup timer - _readyReadBackupTimer->start(); - // grab a time point we can mark as the receive time of this packet auto receiveTime = p_high_resolution_clock::now(); - // setup a HifiSockAddr to read into - HifiSockAddr senderSockAddr; // setup a buffer to read the packet into auto buffer = std::unique_ptr(new char[packetSizeWithHeader]); + QHostAddress senderAddress; + quint16 senderPort; + // pull the datagram auto sizeRead = _udpSocket.readDatagram(buffer.get(), packetSizeWithHeader, - senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer()); + &senderAddress, &senderPort); - // save information for this packet, in case it is the one that sticks readyRead - _lastPacketSizeRead = sizeRead; - _lastPacketSockAddr = senderSockAddr; + // we either didn't pull anything for this packet or there was an error reading (this seems to trigger + // on windows even if there's not a packet available) - if (sizeRead <= 0) { - // we either didn't pull anything for this packet or there was an error reading (this seems to trigger - // on windows even if there's not a packet available) + if (packetSizeWithHeader < 0) { continue; } + _incomingDatagrams.push({ senderAddress, senderPort, packetSizeWithHeader, + std::move(buffer), receiveTime }); + ++packetsRead; + + } + + _maxDatagramsRead = std::max(_maxDatagramsRead, packetsRead); + emit pendingDatagrams(packetsRead); +} + +void Socket::processPendingDatagrams(int) { + // setup a HifiSockAddr to read into + HifiSockAddr senderSockAddr; + + while (!_incomingDatagrams.empty()) { + auto& datagram = _incomingDatagrams.front(); + senderSockAddr.setAddress(datagram._senderAddress); + senderSockAddr.setPort(datagram._senderPort); + int datagramSize = datagram._datagramLength; + auto receiveTime = datagram._receiveTime; + auto it = _unfilteredHandlers.find(senderSockAddr); if (it != _unfilteredHandlers.end()) { // we have a registered unfiltered handler for this HifiSockAddr - call that and return if (it->second) { - auto basePacket = BasePacket::fromReceivedPacket(std::move(buffer), packetSizeWithHeader, senderSockAddr); - basePacket->setReceiveTime(receiveTime); + auto basePacket = BasePacket::fromReceivedPacket(std::move(datagram._datagram), datagramSize, + senderSockAddr); + basePacket->setReceiveTime(datagram._receiveTime); it->second(std::move(basePacket)); } + _incomingDatagrams.pop(); continue; } + // we're reading a packet so re-start the readyRead backup timer + _readyReadBackupTimer->start(); + + // save information for this packet, in case it is the one that sticks readyRead + _lastPacketSizeRead = datagramSize; + _lastPacketSockAddr = senderSockAddr; + // check if this was a control packet or a data packet - bool isControlPacket = *reinterpret_cast(buffer.get()) & CONTROL_BIT_MASK; + bool isControlPacket = *reinterpret_cast(datagram._datagram.get()) & CONTROL_BIT_MASK; if (isControlPacket) { // setup a control packet from the data we just read - auto controlPacket = ControlPacket::fromReceivedPacket(std::move(buffer), packetSizeWithHeader, senderSockAddr); + auto controlPacket = ControlPacket::fromReceivedPacket(std::move(datagram._datagram), datagramSize, senderSockAddr); controlPacket->setReceiveTime(receiveTime); // move this control packet to the matching connection, if there is one @@ -375,7 +401,7 @@ void Socket::readPendingDatagrams() { } else { // setup a Packet from the data we just read - auto packet = Packet::fromReceivedPacket(std::move(buffer), packetSizeWithHeader, senderSockAddr); + auto packet = Packet::fromReceivedPacket(std::move(datagram._datagram), datagramSize, senderSockAddr); packet->setReceiveTime(receiveTime); // save the sequence number in case this is the packet that sticks readyRead @@ -395,6 +421,7 @@ void Socket::readPendingDatagrams() { qCDebug(networking) << "Can't process packet: version" << (unsigned int)NLPacket::versionInHeader(*packet) << ", type" << NLPacket::typeInHeader(*packet); #endif + _incomingDatagrams.pop(); continue; } } @@ -410,6 +437,8 @@ void Socket::readPendingDatagrams() { } } } + + _incomingDatagrams.pop(); } } diff --git a/libraries/networking/src/udt/Socket.h b/libraries/networking/src/udt/Socket.h index 1f28592c83..d23e0425a0 100644 --- a/libraries/networking/src/udt/Socket.h +++ b/libraries/networking/src/udt/Socket.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -94,6 +95,7 @@ public: signals: void clientHandshakeRequestComplete(const HifiSockAddr& sockAddr); + void pendingDatagrams(int datagramCount); public slots: void cleanupConnection(HifiSockAddr sockAddr); @@ -101,6 +103,7 @@ public slots: private slots: void readPendingDatagrams(); + void processPendingDatagrams(int datagramCount); void checkForReadyReadBackup(); void handleSocketError(QAbstractSocket::SocketError socketError); @@ -144,6 +147,17 @@ private: int _lastPacketSizeRead { 0 }; SequenceNumber _lastReceivedSequenceNumber; HifiSockAddr _lastPacketSockAddr; + + struct Datagram { + QHostAddress _senderAddress; + int _senderPort; + int _datagramLength; + std::unique_ptr _datagram; + std::chrono::time_point _receiveTime; + }; + + std::queue _incomingDatagrams; + int _maxDatagramsRead { 0 }; friend UDTTest; }; From 54aeac5d1f8b27717557ce546f020ef265a4505e Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Tue, 21 Aug 2018 15:55:00 -0700 Subject: [PATCH 055/545] adding fix --- libraries/ui/src/ui/TabletScriptingInterface.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libraries/ui/src/ui/TabletScriptingInterface.cpp b/libraries/ui/src/ui/TabletScriptingInterface.cpp index 4e920e430b..1081f8c4e7 100644 --- a/libraries/ui/src/ui/TabletScriptingInterface.cpp +++ b/libraries/ui/src/ui/TabletScriptingInterface.cpp @@ -140,8 +140,7 @@ int TabletButtonsProxyModel::buttonIndex(const QString &uuid) { return -1; } -void TabletButtonsProxyModel::setPageIndex(int pageIndex) -{ +void TabletButtonsProxyModel::setPageIndex(int pageIndex) { if (_pageIndex == pageIndex) return; @@ -465,6 +464,9 @@ void TabletProxy::onTabletShown() { _showRunningScripts = false; pushOntoStack("hifi/dialogs/TabletRunningScripts.qml"); } + if (_currentPathLoaded == TABLET_HOME_SOURCE_URL) { + loadHomeScreen(true); + } } } From 81d0e212dd737b34f43f2f0fff845855a06ee0f9 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Tue, 21 Aug 2018 15:57:17 -0700 Subject: [PATCH 056/545] removing print statements --- interface/resources/qml/hifi/tablet/TabletHome.qml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/interface/resources/qml/hifi/tablet/TabletHome.qml b/interface/resources/qml/hifi/tablet/TabletHome.qml index 10a9f01337..cccd37ad95 100644 --- a/interface/resources/qml/hifi/tablet/TabletHome.qml +++ b/interface/resources/qml/hifi/tablet/TabletHome.qml @@ -117,7 +117,6 @@ Item { id: pageRepeater model: Math.ceil(tabletProxy.buttons.rowCount() / TabletEnums.ButtonsOnPage) onItemAdded: { - console.log("onItemAdded: " + tabletProxy.buttons.rowCount()); item.proxyModel.sourceModel = tabletProxy.buttons; item.proxyModel.pageIndex = index; } @@ -209,7 +208,6 @@ Item { Component.onCompleted: updateProperties() function updateProperties() { - console.log("updateProperties: " + tabletProxy.buttons.rowCount()); var keys = Object.keys(modelData.properties).forEach(function (key) { if (tabletButton[key] !== modelData.properties[key]) { tabletButton[key] = modelData.properties[key]; @@ -272,9 +270,6 @@ Item { anchors.horizontalCenter: parent.horizontalCenter count: swipeView.count - Component.onCompleted: { - console.log("pageIndicator: " + pageIndicator.count); - } } } From bb176eb22834b01d6c1e89d38f18533240f5cef7 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Tue, 21 Aug 2018 16:00:01 -0700 Subject: [PATCH 057/545] trailing debug statements --- interface/resources/qml/hifi/tablet/TabletHome.qml | 1 - scripts/system/menu.js | 1 - scripts/system/tablet-ui/tabletUI.js | 4 +--- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/interface/resources/qml/hifi/tablet/TabletHome.qml b/interface/resources/qml/hifi/tablet/TabletHome.qml index cccd37ad95..1922b02f93 100644 --- a/interface/resources/qml/hifi/tablet/TabletHome.qml +++ b/interface/resources/qml/hifi/tablet/TabletHome.qml @@ -269,7 +269,6 @@ Item { anchors.bottom: parent.bottom anchors.horizontalCenter: parent.horizontalCenter count: swipeView.count - } } diff --git a/scripts/system/menu.js b/scripts/system/menu.js index 1db210216a..d669d3d918 100644 --- a/scripts/system/menu.js +++ b/scripts/system/menu.js @@ -52,7 +52,6 @@ var HOME_BUTTON_TEXTURE = "http://hifi-content.s3.amazonaws.com/alan/dev/tablet- if (isHMDMode) { button = tablet.addButton(buttonProperties); button.clicked.connect(onClicked); - print("Adding menu button"); } else if (button) { button.clicked.disconnect(onClicked); tablet.removeButton(button); diff --git a/scripts/system/tablet-ui/tabletUI.js b/scripts/system/tablet-ui/tabletUI.js index c28040000b..d78e90b789 100644 --- a/scripts/system/tablet-ui/tabletUI.js +++ b/scripts/system/tablet-ui/tabletUI.js @@ -22,7 +22,7 @@ var DEFAULT_TABLET_SCALE = 70; var preMakeTime = Date.now(); var validCheckTime = Date.now(); - var debugTablet = true; + var debugTablet = false; var tabletScalePercentage = 70.0; var UIWebTablet = null; var MSECS_PER_SEC = 1000.0; @@ -298,7 +298,6 @@ } wantsMenu = clicked; }); - clickMapping.from(Controller.Standard.LeftSecondaryThumb).peek().to(function (clicked) { if (clicked) { //activeHudPoint2d(Controller.Standard.LeftHand); @@ -306,7 +305,6 @@ } wantsMenu = clicked; }); - clickMapping.from(Controller.Standard.Start).peek().to(function (clicked) { if (clicked) { //activeHudPoint2dGamePad(); From 4e9a5446187187ffcba87a846ec1b22f36cdbf15 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Tue, 21 Aug 2018 16:01:24 -0700 Subject: [PATCH 058/545] redoing newline --- scripts/system/tablet-ui/tabletUI.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/system/tablet-ui/tabletUI.js b/scripts/system/tablet-ui/tabletUI.js index d78e90b789..80ddbeca8b 100644 --- a/scripts/system/tablet-ui/tabletUI.js +++ b/scripts/system/tablet-ui/tabletUI.js @@ -298,6 +298,7 @@ } wantsMenu = clicked; }); + clickMapping.from(Controller.Standard.LeftSecondaryThumb).peek().to(function (clicked) { if (clicked) { //activeHudPoint2d(Controller.Standard.LeftHand); @@ -305,6 +306,7 @@ } wantsMenu = clicked; }); + clickMapping.from(Controller.Standard.Start).peek().to(function (clicked) { if (clicked) { //activeHudPoint2dGamePad(); From 4084973cca6d1193e681f53c9acddbc9870a0e38 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Tue, 21 Aug 2018 16:04:08 -0700 Subject: [PATCH 059/545] Changes for linux compilation --- libraries/networking/src/udt/Socket.cpp | 2 +- libraries/networking/src/udt/Socket.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/networking/src/udt/Socket.cpp b/libraries/networking/src/udt/Socket.cpp index d01b937b8b..090beb2726 100644 --- a/libraries/networking/src/udt/Socket.cpp +++ b/libraries/networking/src/udt/Socket.cpp @@ -337,7 +337,7 @@ void Socket::readPendingDatagrams() { // we either didn't pull anything for this packet or there was an error reading (this seems to trigger // on windows even if there's not a packet available) - if (packetSizeWithHeader < 0) { + if (sizeRead < 0) { continue; } diff --git a/libraries/networking/src/udt/Socket.h b/libraries/networking/src/udt/Socket.h index d23e0425a0..078863663f 100644 --- a/libraries/networking/src/udt/Socket.h +++ b/libraries/networking/src/udt/Socket.h @@ -153,7 +153,7 @@ private: int _senderPort; int _datagramLength; std::unique_ptr _datagram; - std::chrono::time_point _receiveTime; + p_high_resolution_clock::time_point _receiveTime; }; std::queue _incomingDatagrams; From 11c1845dfa2ca7e1e01abc663582fff876562dbb Mon Sep 17 00:00:00 2001 From: amantley Date: Tue, 21 Aug 2018 16:11:45 -0700 Subject: [PATCH 060/545] added rotate script changes that allow using the hand hip azimuth --- scripts/developer/rotateApp.js | 340 +++++++++++++++++++++++++++++++++ 1 file changed, 340 insertions(+) create mode 100644 scripts/developer/rotateApp.js diff --git a/scripts/developer/rotateApp.js b/scripts/developer/rotateApp.js new file mode 100644 index 0000000000..d65eedfbbe --- /dev/null +++ b/scripts/developer/rotateApp.js @@ -0,0 +1,340 @@ +/* global Script, Vec3, MyAvatar, Tablet, Messages, Quat, +DebugDraw, Mat4, Entities, Xform, Controller, Camera, console, document*/ + +Script.registerValue("ROTATEAPP", true); + +var TABLET_BUTTON_NAME = "ROTATE"; +var CHANGE_OF_BASIS_ROTATION = { x: 0, y: 1, z: 0, w: 0 }; +var DEFAULT_HEAD_TURN_THRESHOLD = 0.5333; +var DEFAULT_HEAD_TURN_FILTER_LENGTH = 4.0; +var LOADING_DELAY = 2000; +var AVERAGING_RATE = 0.03; +var INCREASING = 1.0; +var DECREASING = -1.0; +var DEGREES_PER_PI_RADIANS = 180.0; +var FILTER_FUDGE_RANGE = 0.9; + +var activated = false; +var documentLoaded = false; +var sciptLoaded = false; +var headPoseAverageOrientation = { x: 0, y: 0, z: 0, w: 1 }; +var hipToLeftHandAverage = 0.0; // { x: 0, y: 0, z: 0, w: 1 }; +var hipToRightHandAverage = 0.0; // { x: 0, y: 0, z: 0, w: 1 }; +var averageAzimuth = 0.0; +var hipsPositionRigSpace = { x: 0, y: 0, z: 0 }; +var spine2PositionRigSpace = { x: 0, y: 0, z: 0 }; +var hipsRotationRigSpace = { x: 0, y: 0, z: 0, w: 1 }; +var spine2RotationRigSpace = { x: 0, y: 0, z: 0, w: 1 }; +var spine2Rotation = { x: 0, y: 0, z: 0, w: 1 }; +var hipToLHandAverage = { x: 0, y: 0, z: 0, w: 1 }; +var hipToRHandAverage = { x: 0, y: 0, z: 0, w: 1 }; + +var ikTypes = { + RotationAndPosition: 0, + RotationOnly: 1, + HmdHead: 2, + HipsRelativeRotationAndPosition: 3, + Spline: 4, + Unknown: 5 +}; + + +var ANIM_VARS = [ + //"headType", + "spine2Type", + //"hipsType", + "spine2Position", + "spine2Rotation", + //"hipsPosition", + //"hipsRotation" +]; + +var handlerId = MyAvatar.addAnimationStateHandler(function (props) { + //print("in callback"); + //print("props spine2 pos: " + props.spine2Position.x + " " + props.spine2Position.y + " " + props.spine2Position.z); + //print("props hip pos: " + props.hipsPosition.x + " " + props.hipsPosition.y + " " + props.hipsPosition.z); + var result = {}; + //{x:0,y:0,z:0} + //result.headType = ikTypes.HmdHead; + //result.hipsType = ikTypes.RotationAndPosition; + //result.hipsPosition = hipsPositionRigSpace; // { x: 0, y: 0, z: 0 }; + //result.hipsRotation = hipsRotationRigSpace;//{ x: 0, y: 0, z: 0, w: 1 }; // + result.spine2Type = ikTypes.Spline; + result.spine2Position = { x: 0, y: 1.3, z: 0 }; + result.spine2Rotation = spine2Rotation; + + return result; +}, ANIM_VARS); + +// define state readings constructor +function StateReading(headPose, rhandPose, lhandPose, diffFromAverageEulers) { + this.headPose = headPose; + this.rhandPose = rhandPose; + this.lhandPose = lhandPose; + this.diffFromAverageEulers = diffFromAverageEulers; +} + +// define current state readings object for holding tracker readings and current differences from averages +var currentStateReadings = new StateReading(Controller.getPoseValue(Controller.Standard.Head), + Controller.getPoseValue(Controller.Standard.RightHand), + Controller.getPoseValue(Controller.Standard.LeftHand), + { x: 0, y: 0, z: 0 }); + +// declare the checkbox constructor +function AppCheckbox(type,id,eventType,isChecked) { + this.type = type; + this.id = id; + this.eventType = eventType; + this.data = {value: isChecked}; +} + +var usingStepResetRotationDirection = new AppCheckbox("checkboxtick", "stepReset", "onStepResetCheckBox", false); +var usingDrawAverageFacing = new AppCheckbox("checkboxtick", "drawAverage", "onDrawAverageFacingCheckBox", false); +var checkBoxArray = new Array(usingStepResetRotationDirection, usingDrawAverageFacing); + +// declare the html slider constructor +function AppProperty(name, type, eventType, signalType, setFunction, initValue, convertToThreshold, convertToSlider, signalOn) { + this.name = name; + this.type = type; + this.eventType = eventType; + this.signalType = signalType; + this.setValue = setFunction; + this.value = initValue; + this.get = function () { + return this.value; + }; + this.convertToThreshold = convertToThreshold; + this.convertToSlider = convertToSlider; +} + +// var HTML_URL = Script.resolvePath("file:///c:/dev/hifi_fork/hifi/scripts/developer/rotateRecenterApp.html"); +var HTML_URL = Script.resolvePath("http://hifi-content.s3.amazonaws.com/angus/stepApp/rotateRecenterApp.html"); +var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); + +// define the sliders +var filterLengthProperty = new AppProperty("#filterLength-slider", "slider", "onFilterLengthSlider", "filterSignal", + setFilterLength, DEFAULT_HEAD_TURN_FILTER_LENGTH, function (num) { + var base = 5; + var shift = 0; + return convertExponential(base, num, INCREASING, shift); + }, function (num) { + var base = 5; + var shift = 0; + return convertLog(base, num, INCREASING, shift); + }, true); +var angleThresholdProperty = new AppProperty("#angleThreshold-slider", "slider", "onAngleThresholdSlider", "angleSignal", + setAngleThreshold, DEFAULT_HEAD_TURN_THRESHOLD, function (num) { + return convertToRadians(num); + }, function (num) { + return convertToDegrees(num); + }, true); + +var propArray = new Array(filterLengthProperty, angleThresholdProperty); + +function setFilterLength(num) { + filterLengthProperty.value = num; + MyAvatar.rotationRecenterFilterLength = filterLengthProperty.value; + +} + +function setAngleThreshold(num) { + angleThresholdProperty.value = num; + MyAvatar.rotationThreshold = angleThresholdProperty.value; +} + +function convertToRadians(num) { + return (num / DEGREES_PER_PI_RADIANS) * Math.PI; +} + +function convertToDegrees(num) { + return (num / Math.PI) * DEGREES_PER_PI_RADIANS; +} + +function getLog(x, y) { + return Math.log(y) / Math.log(x); +} + +function convertLog(base, num, direction, shift) { + return direction * getLog(base, (num + FILTER_FUDGE_RANGE)) + shift; +} + +function convertExponential(base, num, direction, shift) { + return Math.pow(base, (direction * num + shift)) - FILTER_FUDGE_RANGE; +} + +function manageClick() { + if (activated) { + tablet.gotoHomeScreen(); + } else { + tablet.gotoWebScreen(HTML_URL); + } +} + +var tabletButton = tablet.addButton({ + text: TABLET_BUTTON_NAME, + icon: Script.resolvePath("http://hifi-content.s3.amazonaws.com/angus/stepApp/foot.svg"), + activeIcon: Script.resolvePath("http://hifi-content.s3.amazonaws.com/angus/stepApp/foot.svg") +}); + +function onKeyPress(event) { + if (event.text === "'") { + // when the sensors are reset, then reset the mode. + } +} + +function onWebEventReceived(msg) { + var message = JSON.parse(msg); + print(" we have a message from html dialog " + message.type); + propArray.forEach(function (prop) { + if (prop.eventType === message.type) { + prop.setValue(prop.convertToThreshold(message.data.value)); + print("message from " + prop.name); + // break; + } + }); + checkBoxArray.forEach(function(cbox) { + if (cbox.eventType === message.type) { + cbox.data.value = message.data.value; + if (cbox.id === "stepReset") { + MyAvatar.enableStepResetRotation = cbox.data.value; + } + if (cbox.id === "drawAverage") { + MyAvatar.enableDrawAverageFacing = cbox.data.value; + } + // break; + } + + }); + if (message.type === "onCreateRotateApp") { + print("document loaded"); + documentLoaded = true; + Script.setTimeout(initAppForm, LOADING_DELAY); + } +} + +function initAppForm() { + print("step app is loaded: " + documentLoaded); + if (documentLoaded === true) { + propArray.forEach(function (prop) { + print(prop.name); + tablet.emitScriptEvent(JSON.stringify({ + "type": "slider", + "id": prop.name, + "data": { "value": prop.convertToSlider(prop.value) } + })); + }); + checkBoxArray.forEach(function (cbox) { + tablet.emitScriptEvent(JSON.stringify({ + "type": "checkboxtick", + "id": cbox.id, + "data": { value: cbox.data.value } + })); + }); + } + +} + + +function onScreenChanged(type, url) { + print("Screen changed"); + if (type === "Web" && url === HTML_URL) { + if (!activated) { + // hook up to event bridge + tablet.webEventReceived.connect(onWebEventReceived); + print("after connect web event"); + MyAvatar.hmdLeanRecenterEnabled = true; + } + activated = true; + } else { + if (activated) { + // disconnect from event bridge + tablet.webEventReceived.disconnect(onWebEventReceived); + documentLoaded = false; + } + activated = false; + } +} + +function limitAngle(angle) { + return (angle + 180) % 360 - 180; +} + +function computeHandAzimuths() { + var leftHand = currentStateReadings.lhandPose.translation; + var rightHand = currentStateReadings.rhandPose.translation; + var head = currentStateReadings.headPose.translation; + var lHandMinusHead = Vec3.subtract(leftHand, head); + lHandMinusHead.y = 0.0; + var rHandMinusHead = Vec3.subtract(rightHand, head); + rHandMinusHead.y = 0.0; + print(JSON.stringify(leftHand)); + print(JSON.stringify(head)); + var avatarZAxis = { x: 0.0, y: 0.0, z: 1.0 }; + var hipToLHand = Quat.lookAtSimple({ x: 0, y: 0, z: 0 }, lHandMinusHead); + var hipToRHand = Quat.lookAtSimple({ x: 0, y: 0, z: 0 }, rHandMinusHead); + hipToLHandAverage = Quat.slerp(hipToLHandAverage, hipToLHand, 0.99); + hipToRHandAverage = Quat.slerp(hipToRHandAverage, hipToRHand, 0.99); + + // var angleToLeft = limitAngle(Quat.safeEulerAngles(hipToLHandAverage).y); + // var angleToRight = limitAngle(Quat.safeEulerAngles(hipToRHandAverage).y); + var leftRightMidpoint = (Quat.safeEulerAngles(hipToLHandAverage).y + Quat.safeEulerAngles(hipToRHandAverage).y) / 2.0; + print(leftRightMidpoint); + + return Quat.fromVec3Degrees({ x: 0, y: leftRightMidpoint, z: 0 }); + + +} + +function update(dt) { + //update state readings + currentStateReadings.head = Controller.getPoseValue(Controller.Standard.Head); + currentStateReadings.rhandPose = Controller.getPoseValue(Controller.Standard.RightHand); + currentStateReadings.lhandPose = Controller.getPoseValue(Controller.Standard.LeftHand); + + print(JSON.stringify(currentStateReadings.head)); + + var latestSpineRotation = computeHandAzimuths(); + var zAxisSpineRotation = Vec3.multiplyQbyV(latestSpineRotation, { x: 0, y: 0, z: 1 }); + var zAxisWorldSpace = Vec3.multiplyQbyV(MyAvatar.rotation, zAxisSpineRotation); + DebugDraw.drawRay(MyAvatar.position, Vec3.sum(MyAvatar.position, zAxisSpineRotation), { x: 1, y: 0, z: 0 }); + spine2Rotation = latestSpineRotation; + /* + if (HMD.active && !scriptLoaded) { + //Script.load("rotateApp.js"); + scriptLoaded = true; + } + + if (!HMD.active) { + scriptLoaded = false; + } + */ + + // handle the azimuth of the arms + +} + +function shutdownTabletApp() { + tablet.removeButton(tabletButton); + if (activated) { + tablet.webEventReceived.disconnect(onWebEventReceived); + tablet.gotoHomeScreen(); + } + tablet.screenChanged.disconnect(onScreenChanged); +} + +Script.setTimeout(function () { + tabletButton.clicked.connect(manageClick); + tablet.screenChanged.connect(onScreenChanged); + Script.update.connect(update); + Controller.keyPressEvent.connect(onKeyPress); +}, (LOADING_DELAY)); + +Script.scriptEnding.connect(function () { + // if (handlerId) { + // print("removing animation state handler"); + // handlerId = MyAvatar.removeAnimationStateHandler(handlerId); + // } + MyAvatar.hmdLeanRecenterEnabled = true; + Script.update.disconnect(update); + shutdownTabletApp(); +}); \ No newline at end of file From d74fef2ea4c68611ca25070fab22458d00219f6f Mon Sep 17 00:00:00 2001 From: amantley Date: Tue, 21 Aug 2018 16:27:47 -0700 Subject: [PATCH 061/545] fixed spine 2 position updating --- scripts/developer/rotateApp.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/developer/rotateApp.js b/scripts/developer/rotateApp.js index d65eedfbbe..ea616b1697 100644 --- a/scripts/developer/rotateApp.js +++ b/scripts/developer/rotateApp.js @@ -60,7 +60,7 @@ var handlerId = MyAvatar.addAnimationStateHandler(function (props) { //result.hipsPosition = hipsPositionRigSpace; // { x: 0, y: 0, z: 0 }; //result.hipsRotation = hipsRotationRigSpace;//{ x: 0, y: 0, z: 0, w: 1 }; // result.spine2Type = ikTypes.Spline; - result.spine2Position = { x: 0, y: 1.3, z: 0 }; + result.spine2Position = spine2PositionRigSpace;// { x: 0, y: 1.3, z: 0 }; result.spine2Rotation = spine2Rotation; return result; @@ -298,6 +298,8 @@ function update(dt) { var zAxisWorldSpace = Vec3.multiplyQbyV(MyAvatar.rotation, zAxisSpineRotation); DebugDraw.drawRay(MyAvatar.position, Vec3.sum(MyAvatar.position, zAxisSpineRotation), { x: 1, y: 0, z: 0 }); spine2Rotation = latestSpineRotation; + var spine2Pos = MyAvatar.getAbsoluteJointTranslationInObjectFrame(MyAvatar.getJointIndex("Spine2")); + spine2PositionRigSpace = Vec3.multiplyQbyV(CHANGE_OF_BASIS_ROTATION, spine2Pos); /* if (HMD.active && !scriptLoaded) { //Script.load("rotateApp.js"); From 5cf6b57f7fa7d374a15f212d43f8541cc080ac8b Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Tue, 21 Aug 2018 17:25:21 -0700 Subject: [PATCH 062/545] removing description - hassle-free fix --- scripts/developer/utilities/audio/Stats.qml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/scripts/developer/utilities/audio/Stats.qml b/scripts/developer/utilities/audio/Stats.qml index 57963732c8..f359e9b04c 100644 --- a/scripts/developer/utilities/audio/Stats.qml +++ b/scripts/developer/utilities/audio/Stats.qml @@ -40,7 +40,8 @@ Column { Section { label: "Latency" - description: "Audio pipeline latency, broken out and summed" + // description: "Audio pipeline latency, broken out and summed" + description: label control: ColumnLayout { MovingValue { label: "Input Read"; source: AudioStats.inputReadMsMax; showGraphs: stats.showGraphs } MovingValue { label: "Input Ring"; source: AudioStats.inputUnplayedMsMax; showGraphs: stats.showGraphs } @@ -62,7 +63,8 @@ Column { Section { label: "Upstream Jitter" - description: "Timegaps in packets sent to the mixer" + // description: "Timegaps in packets sent to the mixer" + description: label control: Jitter { max: AudioStats.sentTimegapMsMaxWindow avg: AudioStats.sentTimegapMsAvgWindow @@ -76,13 +78,15 @@ Column { Section { label: "Mixer (upstream)" - description: "This client's remote audio stream, as seen by the server's mixer" + // description: "This client's remote audio stream, as seen by the server's mixer" + description: label control: Stream { stream: AudioStats.mixerStream; showGraphs: stats.showGraphs } } Section { label: "Client (downstream)" - description: "This client's received audio stream, between the network and the OS" + // description: "This client's received audio stream, between the network and the OS" + description: label control: Stream { stream: AudioStats.clientStream; showGraphs: stats.showGraphs } } } From 26a30edec9f2d1c659d65b598a9bb9844c77040f Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Tue, 21 Aug 2018 18:27:21 -0700 Subject: [PATCH 063/545] trying to fix loading bar --- interface/src/Application.h | 2 ++ .../src/octree/OctreePacketProcessor.cpp | 4 ++++ interface/src/octree/OctreePacketProcessor.h | 1 + interface/src/octree/SafeLanding.cpp | 18 +++++++++++++++ interface/src/octree/SafeLanding.h | 2 ++ .../scripting/WindowScriptingInterface.cpp | 12 ++-------- .../src/scripting/WindowScriptingInterface.h | 4 +--- scripts/system/interstitialPage.js | 23 ++++++------------- 8 files changed, 37 insertions(+), 29 deletions(-) diff --git a/interface/src/Application.h b/interface/src/Application.h index 312920c4ac..db637f57e8 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -232,6 +232,8 @@ public: bool getPreferAvatarFingerOverStylus() { return false; } void setPreferAvatarFingerOverStylus(bool value); + float getDomainLoadProgress() { return _octreeProcessor.domainLoadProgress(); } + float getSettingConstrainToolbarPosition() { return _constrainToolbarPosition.get(); } void setSettingConstrainToolbarPosition(bool setting); diff --git a/interface/src/octree/OctreePacketProcessor.cpp b/interface/src/octree/OctreePacketProcessor.cpp index 4bc6817a9e..11f6bbae13 100644 --- a/interface/src/octree/OctreePacketProcessor.cpp +++ b/interface/src/octree/OctreePacketProcessor.cpp @@ -137,3 +137,7 @@ void OctreePacketProcessor::startEntitySequence() { bool OctreePacketProcessor::isLoadSequenceComplete() const { return _safeLanding->isLoadSequenceComplete(); } + +float OctreePacketProcessor::domainLoadProgress() { + return _safeLanding->loadingProgressPercentage(); +} diff --git a/interface/src/octree/OctreePacketProcessor.h b/interface/src/octree/OctreePacketProcessor.h index f9c24ddc51..fb8f0b581a 100644 --- a/interface/src/octree/OctreePacketProcessor.h +++ b/interface/src/octree/OctreePacketProcessor.h @@ -27,6 +27,7 @@ public: void startEntitySequence(); bool isLoadSequenceComplete() const; + float domainLoadProgress(); signals: void packetVersionMismatch(); diff --git a/interface/src/octree/SafeLanding.cpp b/interface/src/octree/SafeLanding.cpp index 31106457fb..8c0d51a344 100644 --- a/interface/src/octree/SafeLanding.cpp +++ b/interface/src/octree/SafeLanding.cpp @@ -53,6 +53,7 @@ void SafeLanding::startEntitySequence(QSharedPointer entityT void SafeLanding::stopEntitySequence() { Locker lock(_lock); _trackingEntities = false; + _maxTrackedEntityCount = 0; _initialStart = INVALID_SEQUENCE; _initialEnd = INVALID_SEQUENCE; _trackedEntities.clear(); @@ -75,6 +76,11 @@ void SafeLanding::addTrackedEntity(const EntityItemID& entityID) { if (hasAABox && downloadedCollisionTypes.count(modelEntity->getShapeType()) != 0) { // Only track entities with downloaded collision bodies. _trackedEntities.emplace(entityID, entity); + int currentTrackedEntityCount = _trackedEntities.size(); + if (currentTrackedEntityCount > _maxTrackedEntityCount) { + _maxTrackedEntityCount = currentTrackedEntityCount; + } + qCDebug(interfaceapp) << "Safe Landing: Tracking entity " << entity->getItemName(); } } @@ -116,6 +122,18 @@ bool SafeLanding::isLoadSequenceComplete() { return !_trackingEntities; } +float SafeLanding::loadingProgressPercentage() { + float percentage = 0; + + if (_maxTrackedEntityCount != 0) { + int trackedEntityCount = _trackedEntities.size(); + percentage = (_maxTrackedEntityCount - trackedEntityCount) / _maxTrackedEntityCount; + } + + qDebug() << "----------> percentage: " << percentage << " <--------"; + return percentage; +} + bool SafeLanding::isSequenceNumbersComplete() { if (_initialStart != INVALID_SEQUENCE) { Locker lock(_lock); diff --git a/interface/src/octree/SafeLanding.h b/interface/src/octree/SafeLanding.h index 210dfbac25..8ef88a055e 100644 --- a/interface/src/octree/SafeLanding.h +++ b/interface/src/octree/SafeLanding.h @@ -29,6 +29,7 @@ public: void setCompletionSequenceNumbers(int first, int last); void noteReceivedsequenceNumber(int sequenceNumber); bool isLoadSequenceComplete(); + float loadingProgressPercentage(); private slots: void addTrackedEntity(const EntityItemID& entityID); @@ -49,6 +50,7 @@ private: static constexpr int INVALID_SEQUENCE = -1; int _initialStart { INVALID_SEQUENCE }; int _initialEnd { INVALID_SEQUENCE }; + int _maxTrackedEntityCount { 0 }; struct SequenceLessThan { bool operator()(const int& a, const int& b) const; diff --git a/interface/src/scripting/WindowScriptingInterface.cpp b/interface/src/scripting/WindowScriptingInterface.cpp index 68be55f88a..f422a6a8fa 100644 --- a/interface/src/scripting/WindowScriptingInterface.cpp +++ b/interface/src/scripting/WindowScriptingInterface.cpp @@ -589,14 +589,6 @@ void WindowScriptingInterface::onMessageBoxSelected(int button) { } -int WindowScriptingInterface::getPhysicsNearbyEntitiesReadyCount() { - return qApp->getNearbyEntitiesReadyCount(); -} - -int WindowScriptingInterface::getPhysicsNearbyEntitiesStabilityCount() { - return qApp->getEntitiesStabilityCount(); -} - -int WindowScriptingInterface::getPhysicsNearbyEntitiesCount() { - return qApp->getNearbyEntitiesCount(); +float WindowScriptingInterface::domainLoadingProgress() { + return qApp->getDomainLoadProgress(); } diff --git a/interface/src/scripting/WindowScriptingInterface.h b/interface/src/scripting/WindowScriptingInterface.h index 7b0b6435f7..3dcd8cfeed 100644 --- a/interface/src/scripting/WindowScriptingInterface.h +++ b/interface/src/scripting/WindowScriptingInterface.h @@ -561,9 +561,7 @@ public slots: */ void closeMessageBox(int id); - int getPhysicsNearbyEntitiesReadyCount(); - int getPhysicsNearbyEntitiesStabilityCount(); - int getPhysicsNearbyEntitiesCount(); + float domainLoadingProgress(); private slots: void onWindowGeometryChanged(const QRect& geometry); diff --git a/scripts/system/interstitialPage.js b/scripts/system/interstitialPage.js index dde3448b11..76d2a8b958 100644 --- a/scripts/system/interstitialPage.js +++ b/scripts/system/interstitialPage.js @@ -344,26 +344,17 @@ var deltaTime = (thisInterval - lastInterval); lastInterval = thisInterval; - var nearbyEntitiesReadyCount = Window.getPhysicsNearbyEntitiesReadyCount(); - var stabilityCount = Window.getPhysicsNearbyEntitiesStabilityCount(); - var nearbyEntitiesCount = Window.getPhysicsNearbyEntitiesCount(); + var domainLoadingProgressPercentage = Window.domainLoadingProgress(); - var stabilityPercentage = (stabilityCount / STABILITY); - if (stabilityPercentage > 1) { - stabilityPercentage = 1; - } - - var stabilityProgress = (MAX_X_SIZE * 0.75) * stabilityPercentage; - - var entitiesLoadedPercentage = 1; - if (nearbyEntitiesCount > 0) { - entitiesLoadedPercentage = nearbyEntitiesReadyCount / nearbyEntitiesCount; - } - var entitiesLoadedProgress = (MAX_X_SIZE * 0.25) * entitiesLoadedPercentage; - var progress = stabilityProgress + entitiesLoadedProgress; + var progress = MAX_X_SIZE * domainLoadingProgressPercentage; + print(progress); if (progress >= target) { target = progress; } + + if (physicsEnabled && target < MAX_X_SIZE) { + target = MAX_X_SIZE; + } currentProgress = lerp(currentProgress, target, 0.2); var properties = { localPosition: { x: (1.85 - (currentProgress / 2) - (-0.029 * (currentProgress / MAX_X_SIZE))), y: -0.935, z: 0.0 }, From 456b8bf2a927c40499cc420b44ae6a18e18070a4 Mon Sep 17 00:00:00 2001 From: amantley Date: Wed, 22 Aug 2018 09:36:52 -0700 Subject: [PATCH 064/545] tweaked the animvars callback to update the spine2 position --- interface/src/avatar/MyAvatar.cpp | 5 ++++ scripts/developer/rotateApp.js | 38 +++++++++++++++++++++---------- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index c3d8b8df4f..04a6d58aae 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -3937,6 +3937,11 @@ void MyAvatar::FollowHelper::prePhysicsUpdate(MyAvatar& myAvatar, const glm::mat myAvatar.setHeadControllerFacingMovingAverage(myAvatar._headControllerFacing); } } + if (!isActive(Rotation) && getForceActivateRotation()) { + activate(Rotation); + myAvatar.setHeadControllerFacingMovingAverage(myAvatar._headControllerFacing); + setForceActivateRotation(false); + } } else { if (!isActive(Horizontal) && (shouldActivateHorizontal(myAvatar, desiredBodyMatrix, currentBodyMatrix) || hasDriveInput)) { activate(Horizontal); diff --git a/scripts/developer/rotateApp.js b/scripts/developer/rotateApp.js index ea616b1697..7794232196 100644 --- a/scripts/developer/rotateApp.js +++ b/scripts/developer/rotateApp.js @@ -44,7 +44,7 @@ var ANIM_VARS = [ "spine2Type", //"hipsType", "spine2Position", - "spine2Rotation", + "spine2Rotation" //"hipsPosition", //"hipsRotation" ]; @@ -60,7 +60,7 @@ var handlerId = MyAvatar.addAnimationStateHandler(function (props) { //result.hipsPosition = hipsPositionRigSpace; // { x: 0, y: 0, z: 0 }; //result.hipsRotation = hipsRotationRigSpace;//{ x: 0, y: 0, z: 0, w: 1 }; // result.spine2Type = ikTypes.Spline; - result.spine2Position = spine2PositionRigSpace;// { x: 0, y: 1.3, z: 0 }; + result.spine2Position = spine2PositionRigSpace; // { x: 0, y: 1.3, z: 0 }; result.spine2Rotation = spine2Rotation; return result; @@ -267,18 +267,34 @@ function computeHandAzimuths() { lHandMinusHead.y = 0.0; var rHandMinusHead = Vec3.subtract(rightHand, head); rHandMinusHead.y = 0.0; - print(JSON.stringify(leftHand)); - print(JSON.stringify(head)); + //print(JSON.stringify(leftHand)); + //print(JSON.stringify(head)); var avatarZAxis = { x: 0.0, y: 0.0, z: 1.0 }; var hipToLHand = Quat.lookAtSimple({ x: 0, y: 0, z: 0 }, lHandMinusHead); var hipToRHand = Quat.lookAtSimple({ x: 0, y: 0, z: 0 }, rHandMinusHead); - hipToLHandAverage = Quat.slerp(hipToLHandAverage, hipToLHand, 0.99); - hipToRHandAverage = Quat.slerp(hipToRHandAverage, hipToRHand, 0.99); + hipToLHandAverage = Quat.slerp(hipToLHandAverage, hipToLHand, AVERAGING_RATE); + hipToRHandAverage = Quat.slerp(hipToRHandAverage, hipToRHand, AVERAGING_RATE); // var angleToLeft = limitAngle(Quat.safeEulerAngles(hipToLHandAverage).y); // var angleToRight = limitAngle(Quat.safeEulerAngles(hipToRHandAverage).y); - var leftRightMidpoint = (Quat.safeEulerAngles(hipToLHandAverage).y + Quat.safeEulerAngles(hipToRHandAverage).y) / 2.0; - print(leftRightMidpoint); + var leftRightMidpoint = (Quat.safeEulerAngles(hipToLHand).y + Quat.safeEulerAngles(hipToRHand).y) / 2.0; + var leftRightMidpointAverage = (Quat.safeEulerAngles(hipToLHandAverage).y + Quat.safeEulerAngles(hipToRHandAverage).y) / 2.0; + + // limit the angle because we are flipped by 180, fix this tomorrow. + // print(leftRightMidpointAverage/180.0); + // print("threshold value " + angleThresholdProperty.value); + // get it into radians too!! + if ((Math.abs(leftRightMidpointAverage/180.0) * Math.PI) > angleThresholdProperty.value) { + print("recenter the feet under the head"); + MyAvatar.triggerRotationRecenter(); + } + + var raySpineRotation = Quat.fromVec3Degrees({ x: 0, y: leftRightMidpointAverage, z: 0 }); + var zAxisSpineRotation = Vec3.multiplyQbyV(raySpineRotation, { x: 0, y: 0, z: -1 }); + var zAxisWorldSpace = Vec3.multiplyQbyV(MyAvatar.orientation, zAxisSpineRotation); + DebugDraw.drawRay(MyAvatar.position, Vec3.sum(MyAvatar.position, zAxisWorldSpace), { x: 1, y: 0, z: 0, w: 1 }); + + //print(leftRightMidpoint); return Quat.fromVec3Degrees({ x: 0, y: leftRightMidpoint, z: 0 }); @@ -291,12 +307,10 @@ function update(dt) { currentStateReadings.rhandPose = Controller.getPoseValue(Controller.Standard.RightHand); currentStateReadings.lhandPose = Controller.getPoseValue(Controller.Standard.LeftHand); - print(JSON.stringify(currentStateReadings.head)); + //print(JSON.stringify(currentStateReadings.head)); var latestSpineRotation = computeHandAzimuths(); - var zAxisSpineRotation = Vec3.multiplyQbyV(latestSpineRotation, { x: 0, y: 0, z: 1 }); - var zAxisWorldSpace = Vec3.multiplyQbyV(MyAvatar.rotation, zAxisSpineRotation); - DebugDraw.drawRay(MyAvatar.position, Vec3.sum(MyAvatar.position, zAxisSpineRotation), { x: 1, y: 0, z: 0 }); + spine2Rotation = latestSpineRotation; var spine2Pos = MyAvatar.getAbsoluteJointTranslationInObjectFrame(MyAvatar.getJointIndex("Spine2")); spine2PositionRigSpace = Vec3.multiplyQbyV(CHANGE_OF_BASIS_ROTATION, spine2Pos); From d8d940b06a26d4eeb0a800c20dfa4cbdcf69b764 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 22 Aug 2018 10:28:32 -0700 Subject: [PATCH 065/545] Cap datagrams-at-once processed; debugging output --- libraries/networking/src/udt/Socket.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/libraries/networking/src/udt/Socket.cpp b/libraries/networking/src/udt/Socket.cpp index 090beb2726..5b64cc0716 100644 --- a/libraries/networking/src/udt/Socket.cpp +++ b/libraries/networking/src/udt/Socket.cpp @@ -319,7 +319,11 @@ void Socket::readPendingDatagrams() { int packetsRead = 0; int packetSizeWithHeader = -1; - while (_udpSocket.hasPendingDatagrams() && (packetSizeWithHeader = _udpSocket.pendingDatagramSize()) != -1) { + // Max datagrams to read before processing: + static const int MAX_DATAGRAMS_CONSECUTIVELY = 10000; + while (_udpSocket.hasPendingDatagrams() + && (packetSizeWithHeader = _udpSocket.pendingDatagramSize()) != -1 + && packetsRead <= MAX_DATAGRAMS_CONSECUTIVELY) { // grab a time point we can mark as the receive time of this packet auto receiveTime = p_high_resolution_clock::now(); @@ -336,7 +340,6 @@ void Socket::readPendingDatagrams() { // we either didn't pull anything for this packet or there was an error reading (this seems to trigger // on windows even if there's not a packet available) - if (sizeRead < 0) { continue; } @@ -347,7 +350,10 @@ void Socket::readPendingDatagrams() { } - _maxDatagramsRead = std::max(_maxDatagramsRead, packetsRead); + if (packetsRead > _maxDatagramsRead) { + _maxDatagramsRead = packetsRead; + qCDebug(networking) << "readPendingDatagrams: Datagrams read:" << packetsRead; + } emit pendingDatagrams(packetsRead); } @@ -365,7 +371,7 @@ void Socket::processPendingDatagrams(int) { auto it = _unfilteredHandlers.find(senderSockAddr); if (it != _unfilteredHandlers.end()) { - // we have a registered unfiltered handler for this HifiSockAddr - call that and return + // we have a registered unfiltered handler for this HifiSockAddr (eg. STUN packet) - call that and return if (it->second) { auto basePacket = BasePacket::fromReceivedPacket(std::move(datagram._datagram), datagramSize, senderSockAddr); @@ -407,7 +413,7 @@ void Socket::processPendingDatagrams(int) { // save the sequence number in case this is the packet that sticks readyRead _lastReceivedSequenceNumber = packet->getSequenceNumber(); - // call our verification operator to see if this packet is verified + // call our hash verification operator to see if this packet is verified if (!_packetFilterOperator || _packetFilterOperator(*packet)) { if (packet->isReliable()) { // if this was a reliable packet then signal the matching connection with the sequence number From 54236e5c59ab8f33a52b1af381b1cbd31c2fdae1 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Wed, 22 Aug 2018 10:58:55 -0700 Subject: [PATCH 066/545] fixing loading bar --- interface/src/octree/SafeLanding.cpp | 42 +++++++++++++--------------- interface/src/octree/SafeLanding.h | 2 +- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/interface/src/octree/SafeLanding.cpp b/interface/src/octree/SafeLanding.cpp index 8c0d51a344..354a4046fa 100644 --- a/interface/src/octree/SafeLanding.cpp +++ b/interface/src/octree/SafeLanding.cpp @@ -66,23 +66,20 @@ void SafeLanding::addTrackedEntity(const EntityItemID& entityID) { EntityItemPointer entity = _entityTree->findEntityByID(entityID); if (entity && !entity->getCollisionless()) { - const auto& entityType = entity->getType(); - if (entityType == EntityTypes::Model) { - ModelEntityItem * modelEntity = std::dynamic_pointer_cast(entity).get(); - static const std::set downloadedCollisionTypes - { SHAPE_TYPE_COMPOUND, SHAPE_TYPE_SIMPLE_COMPOUND, SHAPE_TYPE_STATIC_MESH, SHAPE_TYPE_SIMPLE_HULL }; - bool hasAABox; - entity->getAABox(hasAABox); - if (hasAABox && downloadedCollisionTypes.count(modelEntity->getShapeType()) != 0) { - // Only track entities with downloaded collision bodies. - _trackedEntities.emplace(entityID, entity); - int currentTrackedEntityCount = _trackedEntities.size(); - if (currentTrackedEntityCount > _maxTrackedEntityCount) { - _maxTrackedEntityCount = currentTrackedEntityCount; - } + static const std::set downloadedCollisionTypes + { SHAPE_TYPE_COMPOUND, SHAPE_TYPE_SIMPLE_COMPOUND, SHAPE_TYPE_STATIC_MESH, SHAPE_TYPE_SIMPLE_HULL }; + bool hasAABox; + entity->getAABox(hasAABox); + if (hasAABox && downloadedCollisionTypes.count(entity->getShapeType()) != 0) { + // Only track entities with downloaded collision bodies. + _trackedEntities.emplace(entityID, entity); - qCDebug(interfaceapp) << "Safe Landing: Tracking entity " << entity->getItemName(); + float trackedEntityCount = (float)_trackedEntities.size(); + + if (trackedEntityCount > _maxTrackedEntityCount) { + _maxTrackedEntityCount = trackedEntityCount; } + qCDebug(interfaceapp) << "Safe Landing: Tracking entity " << entity->getItemName(); } } } @@ -123,15 +120,15 @@ bool SafeLanding::isLoadSequenceComplete() { } float SafeLanding::loadingProgressPercentage() { - float percentage = 0; - - if (_maxTrackedEntityCount != 0) { - int trackedEntityCount = _trackedEntities.size(); - percentage = (_maxTrackedEntityCount - trackedEntityCount) / _maxTrackedEntityCount; + Locker lock(_lock); + if (_maxTrackedEntityCount > 0) { + float trackedEntityCount = (float)_trackedEntities.size(); + qDebug() << "pocessed: " << (_maxTrackedEntityCount - trackedEntityCount) << " -> total: " << _maxTrackedEntityCount; + qDebug() << ((_maxTrackedEntityCount - trackedEntityCount) / _maxTrackedEntityCount); + return ((_maxTrackedEntityCount - trackedEntityCount) / _maxTrackedEntityCount); } - qDebug() << "----------> percentage: " << percentage << " <--------"; - return percentage; + return 0.0f; } bool SafeLanding::isSequenceNumbersComplete() { @@ -158,6 +155,7 @@ bool SafeLanding::isEntityPhysicsComplete() { auto entity = entityMapIter->second; if (!entity->shouldBePhysical() || entity->isReadyToComputeShape()) { entityMapIter = _trackedEntities.erase(entityMapIter); + qDebug() << "--> removing entity <--"; if (entityMapIter == _trackedEntities.end()) { break; } diff --git a/interface/src/octree/SafeLanding.h b/interface/src/octree/SafeLanding.h index 8ef88a055e..e1288f86ce 100644 --- a/interface/src/octree/SafeLanding.h +++ b/interface/src/octree/SafeLanding.h @@ -50,7 +50,7 @@ private: static constexpr int INVALID_SEQUENCE = -1; int _initialStart { INVALID_SEQUENCE }; int _initialEnd { INVALID_SEQUENCE }; - int _maxTrackedEntityCount { 0 }; + float _maxTrackedEntityCount { 0.0f }; struct SequenceLessThan { bool operator()(const int& a, const int& b) const; From e08d8e904651afe946a6400b3027aae9c6de09b9 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 22 Aug 2018 21:03:29 +0200 Subject: [PATCH 067/545] only show InteractiveWindow on top of interface window --- libraries/ui/src/InteractiveWindow.cpp | 30 ++++++++++++++++++++++++++ libraries/ui/src/InteractiveWindow.h | 4 ++++ libraries/ui/src/MainWindow.cpp | 13 +++++++++++ libraries/ui/src/MainWindow.h | 2 ++ libraries/ui/src/OffscreenUi.cpp | 16 ++------------ 5 files changed, 51 insertions(+), 14 deletions(-) diff --git a/libraries/ui/src/InteractiveWindow.cpp b/libraries/ui/src/InteractiveWindow.cpp index 5078fcb602..b4d5a068eb 100644 --- a/libraries/ui/src/InteractiveWindow.cpp +++ b/libraries/ui/src/InteractiveWindow.cpp @@ -13,12 +13,19 @@ #include #include +#include +#include #include #include #include "OffscreenUi.h" #include "shared/QtHelpers.h" +#include "MainWindow.h" + +#ifdef Q_OS_WIN +#include +#endif static auto CONTENT_WINDOW_QML = QUrl("InteractiveWindow.qml"); @@ -87,6 +94,11 @@ InteractiveWindow::InteractiveWindow(const QString& sourceUrl, const QVariantMap connect(object, SIGNAL(windowClosed()), this, SIGNAL(closed()), Qt::QueuedConnection); connect(object, SIGNAL(selfDestruct()), this, SLOT(close()), Qt::QueuedConnection); +#ifdef Q_OS_WIN + connect(object, SIGNAL(nativeWindowChanged()), this, SLOT(parentNativeWindowToMainWindow()), Qt::QueuedConnection); + connect(object, SIGNAL(interactiveWindowVisibleChanged()), this, SLOT(parentNativeWindowToMainWindow()), Qt::QueuedConnection); +#endif + QUrl sourceURL{ sourceUrl }; // If the passed URL doesn't correspond to a known scheme, assume it's a local file path if (!KNOWN_SCHEMES.contains(sourceURL.scheme(), Qt::CaseInsensitive)) { @@ -279,6 +291,24 @@ int InteractiveWindow::getPresentationMode() const { return _qmlWindow->property(PRESENTATION_MODE_PROPERTY).toInt(); } +#ifdef Q_OS_WIN +void InteractiveWindow::parentNativeWindowToMainWindow() { + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "parentNativeWindowToMainWindow"); + return; + } + if (_qmlWindow.isNull()) { + return; + } + const auto nativeWindowProperty = _qmlWindow->property("nativeWindow"); + if (nativeWindowProperty.isNull() || !nativeWindowProperty.isValid()) { + return; + } + const auto nativeWindow = qvariant_cast(nativeWindowProperty); + SetWindowLongPtr((HWND)nativeWindow->winId(), GWLP_HWNDPARENT, (LONG)MainWindow::findMainWindow()->winId()); +} +#endif + void InteractiveWindow::setPresentationMode(int presentationMode) { if (QThread::currentThread() != thread()) { QMetaObject::invokeMethod(this, "setPresentationMode", Q_ARG(int, presentationMode)); diff --git a/libraries/ui/src/InteractiveWindow.h b/libraries/ui/src/InteractiveWindow.h index bf832550b5..f456b32e8d 100644 --- a/libraries/ui/src/InteractiveWindow.h +++ b/libraries/ui/src/InteractiveWindow.h @@ -84,6 +84,10 @@ private: Q_INVOKABLE void setPresentationMode(int presentationMode); Q_INVOKABLE int getPresentationMode() const; +#ifdef Q_OS_WIN + Q_INVOKABLE void parentNativeWindowToMainWindow(); +#endif + public slots: /**jsdoc diff --git a/libraries/ui/src/MainWindow.cpp b/libraries/ui/src/MainWindow.cpp index f9fc71e417..1a13194974 100644 --- a/libraries/ui/src/MainWindow.cpp +++ b/libraries/ui/src/MainWindow.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include "ui/Logging.h" @@ -39,6 +40,18 @@ MainWindow::~MainWindow() { qCDebug(uiLogging) << "Destroying main window"; } +QWindow* MainWindow::findMainWindow() { + auto windows = qApp->topLevelWindows(); + QWindow* result = nullptr; + for (auto window : windows) { + if (window->objectName().contains("MainWindow")) { + result = window; + break; + } + } + return result; +} + void MainWindow::restoreGeometry() { // Did not use setGeometry() on purpose, // see http://doc.qt.io/qt-5/qsettings.html#restoring-the-state-of-a-gui-application diff --git a/libraries/ui/src/MainWindow.h b/libraries/ui/src/MainWindow.h index 75421340a2..fbd48e5eb1 100644 --- a/libraries/ui/src/MainWindow.h +++ b/libraries/ui/src/MainWindow.h @@ -21,6 +21,8 @@ class MainWindow : public QMainWindow { public: explicit MainWindow(QWidget* parent = NULL); ~MainWindow(); + + static QWindow* findMainWindow(); public slots: void restoreGeometry(); diff --git a/libraries/ui/src/OffscreenUi.cpp b/libraries/ui/src/OffscreenUi.cpp index a5ef1457db..d82cfbbf3f 100644 --- a/libraries/ui/src/OffscreenUi.cpp +++ b/libraries/ui/src/OffscreenUi.cpp @@ -29,6 +29,7 @@ #include "ui/Logging.h" #include +#include "MainWindow.h" /**jsdoc * @namespace OffscreenFlags @@ -649,20 +650,7 @@ public: } private: - - static QWindow* findMainWindow() { - auto windows = qApp->topLevelWindows(); - QWindow* result = nullptr; - for (auto window : windows) { - if (window->objectName().contains("MainWindow")) { - result = window; - break; - } - } - return result; - } - - QWindow* const _mainWindow { findMainWindow() }; + QWindow* const _mainWindow { MainWindow::findMainWindow() }; QWindow* _hackWindow { nullptr }; }; From 1e3ca6f902fc9df3cab552c5ebb9a260ddb685df Mon Sep 17 00:00:00 2001 From: amantley Date: Wed, 22 Aug 2018 12:57:06 -0700 Subject: [PATCH 068/545] added quicker follow code and added head to rotate calculation --- interface/src/avatar/MyAvatar.cpp | 21 +++++++++------- libraries/shared/src/AvatarConstants.h | 2 +- scripts/developer/rotateApp.js | 33 +++++++++++++++++++------- 3 files changed, 38 insertions(+), 18 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 04a6d58aae..c79f589b15 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -3797,7 +3797,7 @@ void MyAvatar::lateUpdatePalms() { } -static const float FOLLOW_TIME = 0.5f; +static const float FOLLOW_TIME = 0.1f; MyAvatar::FollowHelper::FollowHelper() { deactivate(); @@ -3902,8 +3902,13 @@ bool MyAvatar::FollowHelper::shouldActivateHorizontalCG(MyAvatar& myAvatar) cons glm::vec3 defaultHeadPosition = myAvatar.getAbsoluteDefaultJointTranslationInObjectFrame(myAvatar.getJointIndex("Head")); glm::vec3 currentHeadPosition = currentHeadPose.getTranslation(); float anatomicalHeadToHipsDistance = glm::length(defaultHeadPosition - defaultHipsPosition); + //if (!isActive(Horizontal) && + // (glm::length(currentHeadPosition - defaultHipsPosition) > (anatomicalHeadToHipsDistance + DEFAULT_AVATAR_SPINE_STRETCH_LIMIT))) { + // myAvatar.setResetMode(true); + // stepDetected = true; + //} if (!isActive(Horizontal) && - (glm::length(currentHeadPosition - defaultHipsPosition) > (anatomicalHeadToHipsDistance + DEFAULT_AVATAR_SPINE_STRETCH_LIMIT))) { + (glm::length(currentHeadPosition - defaultHipsPosition) > (anatomicalHeadToHipsDistance + (DEFAULT_AVATAR_SPINE_STRETCH_LIMIT * anatomicalHeadToHipsDistance * myAvatar.getAvatarScale())))) { myAvatar.setResetMode(true); stepDetected = true; } @@ -3925,10 +3930,15 @@ void MyAvatar::FollowHelper::prePhysicsUpdate(MyAvatar& myAvatar, const glm::mat if (myAvatar.getHMDLeanRecenterEnabled() && qApp->getCamera().getMode() != CAMERA_MODE_MIRROR) { - if (!isActive(Rotation) && (shouldActivateRotation(myAvatar, desiredBodyMatrix, currentBodyMatrix) || hasDriveInput)) { + if (!isActive(Rotation) && getForceActivateRotation()) { activate(Rotation); myAvatar.setHeadControllerFacingMovingAverage(myAvatar._headControllerFacing); + setForceActivateRotation(false); } + //if (!isActive(Rotation) && (shouldActivateRotation(myAvatar, desiredBodyMatrix, currentBodyMatrix) || hasDriveInput)) { + // activate(Rotation); + // myAvatar.setHeadControllerFacingMovingAverage(myAvatar._headControllerFacing); + //} if (myAvatar.getCenterOfGravityModelEnabled()) { if (!isActive(Horizontal) && (shouldActivateHorizontalCG(myAvatar) || hasDriveInput)) { activate(Horizontal); @@ -3937,11 +3947,6 @@ void MyAvatar::FollowHelper::prePhysicsUpdate(MyAvatar& myAvatar, const glm::mat myAvatar.setHeadControllerFacingMovingAverage(myAvatar._headControllerFacing); } } - if (!isActive(Rotation) && getForceActivateRotation()) { - activate(Rotation); - myAvatar.setHeadControllerFacingMovingAverage(myAvatar._headControllerFacing); - setForceActivateRotation(false); - } } else { if (!isActive(Horizontal) && (shouldActivateHorizontal(myAvatar, desiredBodyMatrix, currentBodyMatrix) || hasDriveInput)) { activate(Horizontal); diff --git a/libraries/shared/src/AvatarConstants.h b/libraries/shared/src/AvatarConstants.h index 39117de7ef..b97f586d32 100644 --- a/libraries/shared/src/AvatarConstants.h +++ b/libraries/shared/src/AvatarConstants.h @@ -34,7 +34,7 @@ const float DEFAULT_HANDS_ANGULAR_VELOCITY_STEPPING_THRESHOLD = 3.3f; const float DEFAULT_HEAD_VELOCITY_STEPPING_THRESHOLD = 0.18f; const float DEFAULT_HEAD_PITCH_STEPPING_TOLERANCE = 7.0f; const float DEFAULT_HEAD_ROLL_STEPPING_TOLERANCE = 7.0f; -const float DEFAULT_AVATAR_SPINE_STRETCH_LIMIT = 0.07f; +const float DEFAULT_AVATAR_SPINE_STRETCH_LIMIT = 0.05f; const float DEFAULT_AVATAR_FORWARD_DAMPENING_FACTOR = 0.5f; const float DEFAULT_AVATAR_LATERAL_DAMPENING_FACTOR = 2.0f; const float DEFAULT_AVATAR_HIPS_MASS = 40.0f; diff --git a/scripts/developer/rotateApp.js b/scripts/developer/rotateApp.js index 7794232196..4d18910335 100644 --- a/scripts/developer/rotateApp.js +++ b/scripts/developer/rotateApp.js @@ -259,7 +259,7 @@ function limitAngle(angle) { return (angle + 180) % 360 - 180; } -function computeHandAzimuths() { +function computeHandAzimuths(timeElapsed) { var leftHand = currentStateReadings.lhandPose.translation; var rightHand = currentStateReadings.rhandPose.translation; var head = currentStateReadings.headPose.translation; @@ -272,8 +272,9 @@ function computeHandAzimuths() { var avatarZAxis = { x: 0.0, y: 0.0, z: 1.0 }; var hipToLHand = Quat.lookAtSimple({ x: 0, y: 0, z: 0 }, lHandMinusHead); var hipToRHand = Quat.lookAtSimple({ x: 0, y: 0, z: 0 }, rHandMinusHead); - hipToLHandAverage = Quat.slerp(hipToLHandAverage, hipToLHand, AVERAGING_RATE); - hipToRHandAverage = Quat.slerp(hipToRHandAverage, hipToRHand, AVERAGING_RATE); + var tau = timeElapsed / filterLengthProperty.value; + hipToLHandAverage = Quat.slerp(hipToLHandAverage, hipToLHand, tau); + hipToRHandAverage = Quat.slerp(hipToRHandAverage, hipToRHand, tau); // var angleToLeft = limitAngle(Quat.safeEulerAngles(hipToLHandAverage).y); // var angleToRight = limitAngle(Quat.safeEulerAngles(hipToRHandAverage).y); @@ -283,11 +284,7 @@ function computeHandAzimuths() { // limit the angle because we are flipped by 180, fix this tomorrow. // print(leftRightMidpointAverage/180.0); // print("threshold value " + angleThresholdProperty.value); - // get it into radians too!! - if ((Math.abs(leftRightMidpointAverage/180.0) * Math.PI) > angleThresholdProperty.value) { - print("recenter the feet under the head"); - MyAvatar.triggerRotationRecenter(); - } + var raySpineRotation = Quat.fromVec3Degrees({ x: 0, y: leftRightMidpointAverage, z: 0 }); var zAxisSpineRotation = Vec3.multiplyQbyV(raySpineRotation, { x: 0, y: 0, z: -1 }); @@ -295,6 +292,22 @@ function computeHandAzimuths() { DebugDraw.drawRay(MyAvatar.position, Vec3.sum(MyAvatar.position, zAxisWorldSpace), { x: 1, y: 0, z: 0, w: 1 }); //print(leftRightMidpoint); + + var headPoseRigSpace = Quat.multiply(CHANGE_OF_BASIS_ROTATION, currentStateReadings.head.rotation); + headPoseAverageOrientation = Quat.slerp(headPoseAverageOrientation, headPoseRigSpace, tau); + var headPoseAverageEulers = Quat.safeEulerAngles(headPoseAverageOrientation); + + // get it into radians too!! + // average head and hands 50/50 + print("hands azimuth " + leftRightMidpointAverage + " head azimuth " + headPoseAverageEulers.y) + var headPlusHands = (leftRightMidpointAverage + headPoseAverageEulers.y) / 2.0; + if ((Math.abs(headPlusHands / 180.0) * Math.PI) > angleThresholdProperty.value) { + print("recenter the feet under the head"); + MyAvatar.triggerRotationRecenter(); + hipToLHandAverage = { x: 0, y: 0, z: 0, w: 1 }; + hipToRHandAverage = { x: 0, y: 0, z: 0, w: 1 }; + headPoseAverageOrientation = { x: 0, y: 0, z: 0, w: 1 }; + } return Quat.fromVec3Degrees({ x: 0, y: leftRightMidpoint, z: 0 }); @@ -309,7 +322,9 @@ function update(dt) { //print(JSON.stringify(currentStateReadings.head)); - var latestSpineRotation = computeHandAzimuths(); + + + var latestSpineRotation = computeHandAzimuths(dt); spine2Rotation = latestSpineRotation; var spine2Pos = MyAvatar.getAbsoluteJointTranslationInObjectFrame(MyAvatar.getJointIndex("Spine2")); From 535fdf32cfbbb89df0775a6899e74c113ac4077e Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Wed, 22 Aug 2018 13:13:00 -0700 Subject: [PATCH 069/545] saving changes --- interface/src/octree/SafeLanding.cpp | 27 +++++++++++++++------------ interface/src/ui/OverlayConductor.cpp | 1 + scripts/system/interstitialPage.js | 20 ++++++++++++++++++++ 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/interface/src/octree/SafeLanding.cpp b/interface/src/octree/SafeLanding.cpp index 354a4046fa..c1556b908d 100644 --- a/interface/src/octree/SafeLanding.cpp +++ b/interface/src/octree/SafeLanding.cpp @@ -66,20 +66,24 @@ void SafeLanding::addTrackedEntity(const EntityItemID& entityID) { EntityItemPointer entity = _entityTree->findEntityByID(entityID); if (entity && !entity->getCollisionless()) { - static const std::set downloadedCollisionTypes - { SHAPE_TYPE_COMPOUND, SHAPE_TYPE_SIMPLE_COMPOUND, SHAPE_TYPE_STATIC_MESH, SHAPE_TYPE_SIMPLE_HULL }; - bool hasAABox; - entity->getAABox(hasAABox); - if (hasAABox && downloadedCollisionTypes.count(entity->getShapeType()) != 0) { - // Only track entities with downloaded collision bodies. - _trackedEntities.emplace(entityID, entity); + const auto& entityType = entity->getType(); + if (entityType == EntityTypes::Model) { + ModelEntityItem * modelEntity = std::dynamic_pointer_cast(entity).get(); + static const std::set downloadedCollisionTypes + { SHAPE_TYPE_COMPOUND, SHAPE_TYPE_SIMPLE_COMPOUND, SHAPE_TYPE_STATIC_MESH, SHAPE_TYPE_SIMPLE_HULL }; + bool hasAABox; + entity->getAABox(hasAABox); + if (hasAABox && downloadedCollisionTypes.count(modelEntity->getShapeType()) != 0) { + // Only track entities with downloaded collision bodies. + _trackedEntities.emplace(entityID, entity); - float trackedEntityCount = (float)_trackedEntities.size(); + float trackedEntityCount = (float)_trackedEntities.size(); - if (trackedEntityCount > _maxTrackedEntityCount) { - _maxTrackedEntityCount = trackedEntityCount; + if (trackedEntityCount > _maxTrackedEntityCount) { + _maxTrackedEntityCount = trackedEntityCount; + } + qCDebug(interfaceapp) << "Safe Landing: Tracking entity " << entity->getItemName(); } - qCDebug(interfaceapp) << "Safe Landing: Tracking entity " << entity->getItemName(); } } } @@ -155,7 +159,6 @@ bool SafeLanding::isEntityPhysicsComplete() { auto entity = entityMapIter->second; if (!entity->shouldBePhysical() || entity->isReadyToComputeShape()) { entityMapIter = _trackedEntities.erase(entityMapIter); - qDebug() << "--> removing entity <--"; if (entityMapIter == _trackedEntities.end()) { break; } diff --git a/interface/src/ui/OverlayConductor.cpp b/interface/src/ui/OverlayConductor.cpp index e27001567f..398f9cf147 100644 --- a/interface/src/ui/OverlayConductor.cpp +++ b/interface/src/ui/OverlayConductor.cpp @@ -103,6 +103,7 @@ void OverlayConductor::update(float dt) { bool targetVisible = Menu::getInstance()->isOptionChecked(MenuOption::Overlays) && !_suppressedByHead; if (targetVisible != currentVisible) { + qDebug() << "setting pinned: " << !targetVisible; offscreenUi->setPinned(!targetVisible); } if (shouldRecenter && !_suppressedByHead) { diff --git a/scripts/system/interstitialPage.js b/scripts/system/interstitialPage.js index 76d2a8b958..ddfc8b3a32 100644 --- a/scripts/system/interstitialPage.js +++ b/scripts/system/interstitialPage.js @@ -207,6 +207,18 @@ return ((1 - t) * a + t * b); } + function resetValues() { + var properties = { + localPosition: { x: 1.85, y: -0.935, z: 0.0 }, + dimensions: { + x: 0.1, + y: 2.8 + } + }; + + Overlays.editOverlay(loadingBarProgress, properties); + } + function startInterstitialPage() { if (timer === null) { updateOverlays(Window.isPhysicsEnabled()); @@ -323,6 +335,10 @@ Overlays.editOverlay(loadingBarPlacard, properties); Overlays.editOverlay(loadingBarProgress, loadingBarProperties); + if (physicsEnabled) { + resetValues(); + } + Camera.mode = "first person"; } @@ -409,6 +425,10 @@ if (DEBUG) { tablet.removeButton(button); } + + renderViewTask.getConfig("LightingModel")["enableAmbientLight"] = true; + renderViewTask.getConfig("LightingModel")["enableDirectionalLight"] = true; + renderViewTask.getConfig("LightingModel")["enablePointLight"] = true; } Script.scriptEnding.connect(cleanup); From 9dfaf32b7240f22e88ea611966e3a4373b2d552a Mon Sep 17 00:00:00 2001 From: amantley Date: Wed, 22 Aug 2018 14:12:19 -0700 Subject: [PATCH 070/545] fixed the step animation but it still needs work --- interface/src/avatar/MyAvatar.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 46a5cbe414..44ee5e30c6 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -3933,6 +3933,9 @@ bool MyAvatar::FollowHelper::shouldActivateVertical(const MyAvatar& myAvatar, co void MyAvatar::FollowHelper::prePhysicsUpdate(MyAvatar& myAvatar, const glm::mat4& desiredBodyMatrix, const glm::mat4& currentBodyMatrix, bool hasDriveInput) { + const float VELOCITY_THRESHHOLD = 1.0f; + float currentVelocity = glm::length(myAvatar.getLocalVelocity() / myAvatar.getSensorToWorldScale()); + if (myAvatar.getHMDLeanRecenterEnabled() && qApp->getCamera().getMode() != CAMERA_MODE_MIRROR) { @@ -3946,7 +3949,7 @@ void MyAvatar::FollowHelper::prePhysicsUpdate(MyAvatar& myAvatar, const glm::mat // myAvatar.setHeadControllerFacingMovingAverage(myAvatar._headControllerFacing); //} if (myAvatar.getCenterOfGravityModelEnabled()) { - if (!isActive(Horizontal) && (shouldActivateHorizontalCG(myAvatar) || hasDriveInput)) { + if ((!isActive(Horizontal) && (shouldActivateHorizontalCG(myAvatar) || hasDriveInput)) || (isActive(Horizontal) && (currentVelocity > VELOCITY_THRESHHOLD))) { activate(Horizontal); if (myAvatar.getEnableStepResetRotation()) { activate(Rotation); From 78458d62de4b6ee94ae1cd2673d1b1c8286584dd Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Wed, 22 Aug 2018 15:20:56 -0700 Subject: [PATCH 071/545] revert some changes and fix toolbar issue --- interface/src/Application.cpp | 3 ++- interface/src/octree/SafeLanding.cpp | 2 -- scripts/system/interstitialPage.js | 2 ++ 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9d5a7a01f8..b437e7bd28 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3458,7 +3458,8 @@ void Application::setIsInterstitialMode(bool interstitialMode) { bool interstitialModeEnabled = menu->isOptionChecked("Enable Interstitial"); if (_interstitialMode != interstitialMode && interstitialModeEnabled) { _interstitialMode = interstitialMode; - menu->setIsOptionChecked(MenuOption::Overlays, !_interstitialMode); + + DependencyManager::get()->setPinned(_interstitialMode); emit interstitialModeChanged(_interstitialMode); } } diff --git a/interface/src/octree/SafeLanding.cpp b/interface/src/octree/SafeLanding.cpp index c1556b908d..d8d9a1720a 100644 --- a/interface/src/octree/SafeLanding.cpp +++ b/interface/src/octree/SafeLanding.cpp @@ -127,8 +127,6 @@ float SafeLanding::loadingProgressPercentage() { Locker lock(_lock); if (_maxTrackedEntityCount > 0) { float trackedEntityCount = (float)_trackedEntities.size(); - qDebug() << "pocessed: " << (_maxTrackedEntityCount - trackedEntityCount) << " -> total: " << _maxTrackedEntityCount; - qDebug() << ((_maxTrackedEntityCount - trackedEntityCount) / _maxTrackedEntityCount); return ((_maxTrackedEntityCount - trackedEntityCount) / _maxTrackedEntityCount); } diff --git a/scripts/system/interstitialPage.js b/scripts/system/interstitialPage.js index ddfc8b3a32..3f1fc58b55 100644 --- a/scripts/system/interstitialPage.js +++ b/scripts/system/interstitialPage.js @@ -27,6 +27,7 @@ var DEFAULT_Z_OFFSET = 5.45; var renderViewTask = Render.getConfig("RenderMainView"); + var toolbar = Toolbars.getToolbar("com.highfidelity.interface.toolbar.system"); var request = Script.require('request').request; var BUTTON_PROPERTIES = { text: "Interstitial" @@ -336,6 +337,7 @@ Overlays.editOverlay(loadingBarProgress, loadingBarProperties); if (physicsEnabled) { + toolbar.writeProperty("visible", true); resetValues(); } From 5c0b12abf6a7d1983dc5a080cf31422c41ee36d3 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 22 Aug 2018 12:07:32 -0700 Subject: [PATCH 072/545] ordered ray/parabola intersection code --- interface/src/avatar/AvatarManager.cpp | 8 +- interface/src/raypick/LaserPointer.cpp | 3 + interface/src/raypick/ParabolaPointer.cpp | 3 + .../src/RenderablePolyVoxEntityItem.cpp | 13 +- libraries/entities/src/EntityTree.cpp | 54 +- libraries/entities/src/EntityTreeElement.cpp | 33 +- libraries/entities/src/EntityTreeElement.h | 9 +- libraries/entities/src/ShapeEntityItem.cpp | 28 +- libraries/octree/src/Octree.cpp | 127 ++--- libraries/octree/src/Octree.h | 22 +- libraries/render-utils/src/Model.cpp | 177 ++++-- libraries/render-utils/src/Model.h | 10 + libraries/shared/src/GeometryUtil.cpp | 7 +- libraries/shared/src/TriangleSet.cpp | 518 +++++++++++------- libraries/shared/src/TriangleSet.h | 25 +- 15 files changed, 589 insertions(+), 448 deletions(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 0d180bc40d..139f44d58b 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -553,8 +553,6 @@ RayToAvatarIntersectionResult AvatarManager::findRayIntersectionVector(const Pic return result; } - glm::vec3 normDirection = glm::normalize(ray.direction); - auto avatarHashCopy = getHashCopy(); for (auto avatarData : avatarHashCopy) { auto avatar = std::static_pointer_cast(avatarData); @@ -587,14 +585,14 @@ RayToAvatarIntersectionResult AvatarManager::findRayIntersectionVector(const Pic glm::vec3 end; float radius; avatar->getCapsule(start, end, radius); - bool intersects = findRayCapsuleIntersection(ray.origin, normDirection, start, end, radius, distance); + bool intersects = findRayCapsuleIntersection(ray.origin, ray.direction, start, end, radius, distance); if (!intersects) { // ray doesn't intersect avatar's capsule continue; } QVariantMap extraInfo; - intersects = avatarModel->findRayIntersectionAgainstSubMeshes(ray.origin, normDirection, + intersects = avatarModel->findRayIntersectionAgainstSubMeshes(ray.origin, ray.direction, distance, face, surfaceNormal, extraInfo, true); if (intersects && (!result.intersects || distance < result.distance)) { @@ -608,7 +606,7 @@ RayToAvatarIntersectionResult AvatarManager::findRayIntersectionVector(const Pic } if (result.intersects) { - result.intersection = ray.origin + normDirection * result.distance; + result.intersection = ray.origin + ray.direction * result.distance; } return result; diff --git a/interface/src/raypick/LaserPointer.cpp b/interface/src/raypick/LaserPointer.cpp index 2382a95105..40a5e5cb69 100644 --- a/interface/src/raypick/LaserPointer.cpp +++ b/interface/src/raypick/LaserPointer.cpp @@ -42,6 +42,9 @@ glm::vec3 LaserPointer::getPickOrigin(const PickResultPointer& pickResult) const glm::vec3 LaserPointer::getPickEnd(const PickResultPointer& pickResult, float distance) const { auto rayPickResult = std::static_pointer_cast(pickResult); + if (!rayPickResult) { + return glm::vec3(0.0f); + } if (distance > 0.0f) { PickRay pick = PickRay(rayPickResult->pickVariant); return pick.origin + distance * pick.direction; diff --git a/interface/src/raypick/ParabolaPointer.cpp b/interface/src/raypick/ParabolaPointer.cpp index 097c98340c..57d57e11c4 100644 --- a/interface/src/raypick/ParabolaPointer.cpp +++ b/interface/src/raypick/ParabolaPointer.cpp @@ -67,6 +67,9 @@ glm::vec3 ParabolaPointer::getPickOrigin(const PickResultPointer& pickResult) co glm::vec3 ParabolaPointer::getPickEnd(const PickResultPointer& pickResult, float distance) const { auto parabolaPickResult = std::static_pointer_cast(pickResult); + if (!parabolaPickResult) { + return glm::vec3(0.0f); + } if (distance > 0.0f) { PickParabola pick = PickParabola(parabolaPickResult->pickVariant); return pick.origin + pick.velocity * distance + 0.5f * pick.acceleration * distance * distance; diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index c11ccb70a0..63f27dd170 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -584,8 +584,6 @@ bool RenderablePolyVoxEntityItem::findDetailedRayIntersection(const glm::vec3& o glm::vec4 originInVoxel = wtvMatrix * glm::vec4(origin, 1.0f); glm::vec4 farInVoxel = wtvMatrix * glm::vec4(farPoint, 1.0f); - glm::vec4 directionInVoxel = glm::normalize(farInVoxel - originInVoxel); - glm::vec4 result = glm::vec4(0.0f, 0.0f, 0.0f, 0.0f); PolyVox::RaycastResult raycastResult = doRayCast(originInVoxel, farInVoxel, result); if (raycastResult == PolyVox::RaycastResults::Completed) { @@ -599,14 +597,9 @@ bool RenderablePolyVoxEntityItem::findDetailedRayIntersection(const glm::vec3& o voxelBox += result3 - Vectors::HALF; voxelBox += result3 + Vectors::HALF; - float voxelDistance; - bool hit = voxelBox.findRayIntersection(glm::vec3(originInVoxel), glm::vec3(directionInVoxel), - voxelDistance, face, surfaceNormal); - - glm::vec4 voxelIntersectionPoint = glm::vec4(glm::vec3(originInVoxel) + glm::vec3(directionInVoxel) * voxelDistance, 1.0); - glm::vec4 intersectionPoint = vtwMatrix * voxelIntersectionPoint; - distance = glm::distance(origin, glm::vec3(intersectionPoint)); - return hit; + glm::vec4 directionInVoxel = wtvMatrix * glm::vec4(direction, 0.0f); + return voxelBox.findRayIntersection(glm::vec3(originInVoxel), glm::vec3(directionInVoxel), + distance, face, surfaceNormal); } bool RenderablePolyVoxEntityItem::findDetailedParabolaIntersection(const glm::vec3& origin, const glm::vec3& velocity, diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 377e192bb1..1cf6e45d5b 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -825,15 +825,38 @@ bool findRayIntersectionOp(const OctreeElementPointer& element, void* extraData) RayArgs* args = static_cast(extraData); bool keepSearching = true; EntityTreeElementPointer entityTreeElementPointer = std::static_pointer_cast(element); - EntityItemID entityID = entityTreeElementPointer->findRayIntersection(args->origin, args->direction, keepSearching, + EntityItemID entityID = entityTreeElementPointer->findRayIntersection(args->origin, args->direction, args->element, args->distance, args->face, args->surfaceNormal, args->entityIdsToInclude, args->entityIdsToDiscard, args->visibleOnly, args->collidableOnly, args->extraInfo, args->precisionPicking); if (!entityID.isNull()) { args->entityID = entityID; + // We recurse OctreeElements in order, so if we hit something, we can stop immediately + keepSearching = false; } return keepSearching; } +float findRayIntersectionSortingOp(const OctreeElementPointer& element, void* extraData) { + RayArgs* args = static_cast(extraData); + EntityTreeElementPointer entityTreeElementPointer = std::static_pointer_cast(element); + float distance = FLT_MAX; + // If origin is inside the cube, always check this element first + if (entityTreeElementPointer->getAACube().contains(args->origin)) { + distance = 0.0f; + } else { + float boundDistance = FLT_MAX; + BoxFace face; + glm::vec3 surfaceNormal; + if (entityTreeElementPointer->getAACube().findRayIntersection(args->origin, args->direction, boundDistance, face, surfaceNormal)) { + // Don't add this cell if it's already farther than our best distance so far + if (boundDistance < args->distance) { + distance = boundDistance; + } + } + } + return distance; +} + EntityItemID EntityTree::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, QVector entityIdsToInclude, QVector entityIdsToDiscard, bool visibleOnly, bool collidableOnly, bool precisionPicking, @@ -846,7 +869,7 @@ EntityItemID EntityTree::findRayIntersection(const glm::vec3& origin, const glm: bool requireLock = lockType == Octree::Lock; bool lockResult = withReadLock([&]{ - recurseTreeWithOperation(findRayIntersectionOp, &args); + recurseTreeWithOperationSorted(findRayIntersectionOp, findRayIntersectionSortingOp, &args); }, requireLock); if (accurateResult) { @@ -860,15 +883,38 @@ bool findParabolaIntersectionOp(const OctreeElementPointer& element, void* extra ParabolaArgs* args = static_cast(extraData); bool keepSearching = true; EntityTreeElementPointer entityTreeElementPointer = std::static_pointer_cast(element); - EntityItemID entityID = entityTreeElementPointer->findParabolaIntersection(args->origin, args->velocity, args->acceleration, keepSearching, + EntityItemID entityID = entityTreeElementPointer->findParabolaIntersection(args->origin, args->velocity, args->acceleration, args->element, args->parabolicDistance, args->face, args->surfaceNormal, args->entityIdsToInclude, args->entityIdsToDiscard, args->visibleOnly, args->collidableOnly, args->extraInfo, args->precisionPicking); if (!entityID.isNull()) { args->entityID = entityID; + // We recurse OctreeElements in order, so if we hit something, we can stop immediately + keepSearching = false; } return keepSearching; } +float findParabolaIntersectionSortingOp(const OctreeElementPointer& element, void* extraData) { + ParabolaArgs* args = static_cast(extraData); + EntityTreeElementPointer entityTreeElementPointer = std::static_pointer_cast(element); + float distance = FLT_MAX; + // If origin is inside the cube, always check this element first + if (entityTreeElementPointer->getAACube().contains(args->origin)) { + distance = 0.0f; + } else { + float boundDistance = FLT_MAX; + BoxFace face; + glm::vec3 surfaceNormal; + if (entityTreeElementPointer->getAACube().findParabolaIntersection(args->origin, args->velocity, args->acceleration, boundDistance, face, surfaceNormal)) { + // Don't add this cell if it's already farther than our best distance so far + if (boundDistance < args->parabolicDistance) { + distance = boundDistance; + } + } + } + return distance; +} + EntityItemID EntityTree::findParabolaIntersection(const PickParabola& parabola, QVector entityIdsToInclude, QVector entityIdsToDiscard, bool visibleOnly, bool collidableOnly, bool precisionPicking, @@ -882,7 +928,7 @@ EntityItemID EntityTree::findParabolaIntersection(const PickParabola& parabola, bool requireLock = lockType == Octree::Lock; bool lockResult = withReadLock([&] { - recurseTreeWithOperation(findParabolaIntersectionOp, &args); + recurseTreeWithOperationSorted(findParabolaIntersectionOp, findParabolaIntersectionSortingOp, &args); }, requireLock); if (accurateResult) { diff --git a/libraries/entities/src/EntityTreeElement.cpp b/libraries/entities/src/EntityTreeElement.cpp index 5974fce6c5..e8e11c0ee1 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -140,27 +140,17 @@ bool EntityTreeElement::bestFitBounds(const glm::vec3& minPoint, const glm::vec3 } EntityItemID EntityTreeElement::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, - bool& keepSearching, OctreeElementPointer& element, float& distance, - BoxFace& face, glm::vec3& surfaceNormal, const QVector& entityIdsToInclude, - const QVector& entityIdsToDiscard, bool visibleOnly, bool collidableOnly, - QVariantMap& extraInfo, bool precisionPicking) { + OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, + const QVector& entityIdsToInclude, const QVector& entityIdsToDiscard, + bool visibleOnly, bool collidableOnly, QVariantMap& extraInfo, bool precisionPicking) { EntityItemID result; - float distanceToElementCube = std::numeric_limits::max(); + float distanceToElementCube = FLT_MAX; BoxFace localFace; glm::vec3 localSurfaceNormal; - // if the ray doesn't intersect with our cube OR the distance to element is less than current best distance - // we can stop searching! - bool hit = _cube.findRayIntersection(origin, direction, distanceToElementCube, localFace, localSurfaceNormal); - if (!hit || (!_cube.contains(origin) && distanceToElementCube > distance)) { - keepSearching = false; // no point in continuing to search - return result; // we did not intersect - } - - // by default, we only allow intersections with leaves with content if (!canPickIntersect()) { - return result; // we don't intersect with non-leaves, and we keep searching + return result; } // if the distance to the element cube is not less than the current best distance, then it's not possible @@ -289,7 +279,7 @@ bool EntityTreeElement::findSpherePenetration(const glm::vec3& center, float rad } EntityItemID EntityTreeElement::findParabolaIntersection(const glm::vec3& origin, const glm::vec3& velocity, - const glm::vec3& acceleration, bool& keepSearching, OctreeElementPointer& element, float& parabolicDistance, + const glm::vec3& acceleration, OctreeElementPointer& element, float& parabolicDistance, BoxFace& face, glm::vec3& surfaceNormal, const QVector& entityIdsToInclude, const QVector& entityIdsToDiscard, bool visibleOnly, bool collidableOnly, QVariantMap& extraInfo, bool precisionPicking) { @@ -299,17 +289,8 @@ EntityItemID EntityTreeElement::findParabolaIntersection(const glm::vec3& origin BoxFace localFace; glm::vec3 localSurfaceNormal; - // if the parabola doesn't intersect with our cube OR the distance to element is less than current best distance - // we can stop searching! - bool hit = _cube.findParabolaIntersection(origin, velocity, acceleration, distanceToElementCube, localFace, localSurfaceNormal); - if (!hit || (!_cube.contains(origin) && distanceToElementCube > parabolicDistance)) { - keepSearching = false; // no point in continuing to search - return result; // we did not intersect - } - - // by default, we only allow intersections with leaves with content if (!canPickIntersect()) { - return result; // we don't intersect with non-leaves, and we keep searching + return result; } // if the distance to the element cube is not less than the current best distance, then it's not possible diff --git a/libraries/entities/src/EntityTreeElement.h b/libraries/entities/src/EntityTreeElement.h index d6f9db08d6..793340c9a4 100644 --- a/libraries/entities/src/EntityTreeElement.h +++ b/libraries/entities/src/EntityTreeElement.h @@ -136,10 +136,9 @@ public: virtual bool canPickIntersect() const override { return hasEntities(); } virtual EntityItemID findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, - bool& keepSearching, OctreeElementPointer& element, float& distance, - BoxFace& face, glm::vec3& surfaceNormal, const QVector& entityIdsToInclude, - const QVector& entityIdsToDiscard, bool visibleOnly, bool collidableOnly, - QVariantMap& extraInfo, bool precisionPicking = false); + OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, + const QVector& entityIdsToInclude, const QVector& entityIdsToDiscard, + bool visibleOnly, bool collidableOnly, QVariantMap& extraInfo, bool precisionPicking = false); virtual EntityItemID findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, const QVector& entityIdsToInclude, @@ -149,7 +148,7 @@ public: glm::vec3& penetration, void** penetratedObject) const override; virtual EntityItemID findParabolaIntersection(const glm::vec3& origin, const glm::vec3& velocity, - const glm::vec3& acceleration, bool& keepSearching, OctreeElementPointer& element, float& parabolicDistance, + const glm::vec3& acceleration, OctreeElementPointer& element, float& parabolicDistance, BoxFace& face, glm::vec3& surfaceNormal, const QVector& entityIdsToInclude, const QVector& entityIdsToDiscard, bool visibleOnly, bool collidableOnly, QVariantMap& extraInfo, bool precisionPicking = false); diff --git a/libraries/entities/src/ShapeEntityItem.cpp b/libraries/entities/src/ShapeEntityItem.cpp index e4ea1470c1..773a7059dc 100644 --- a/libraries/entities/src/ShapeEntityItem.cpp +++ b/libraries/entities/src/ShapeEntityItem.cpp @@ -262,20 +262,18 @@ bool ShapeEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const glm::mat4 entityToWorldMatrix = getEntityToWorldMatrix(); glm::mat4 worldToEntityMatrix = glm::inverse(entityToWorldMatrix); glm::vec3 entityFrameOrigin = glm::vec3(worldToEntityMatrix * glm::vec4(origin, 1.0f)); - glm::vec3 entityFrameDirection = glm::normalize(glm::vec3(worldToEntityMatrix * glm::vec4(direction, 0.0f))); + glm::vec3 entityFrameDirection = glm::vec3(worldToEntityMatrix * glm::vec4(direction, 0.0f)); - float localDistance; // NOTE: unit sphere has center of 0,0,0 and radius of 0.5 - if (findRaySphereIntersection(entityFrameOrigin, entityFrameDirection, glm::vec3(0.0f), 0.5f, localDistance)) { - // determine where on the unit sphere the hit point occured - glm::vec3 entityFrameHitAt = entityFrameOrigin + (entityFrameDirection * localDistance); - // then translate back to work coordinates - glm::vec3 hitAt = glm::vec3(entityToWorldMatrix * glm::vec4(entityFrameHitAt, 1.0f)); - distance = glm::distance(origin, hitAt); + if (findRaySphereIntersection(entityFrameOrigin, entityFrameDirection, glm::vec3(0.0f), 0.5f, distance)) { bool success; - // FIXME: this is only correct for uniformly scaled spheres - surfaceNormal = glm::normalize(hitAt - getCenterPosition(success)); - if (!success) { + glm::vec3 center = getCenterPosition(success); + if (success) { + // FIXME: this is only correct for uniformly scaled spheres + // determine where on the unit sphere the hit point occured + glm::vec3 hitAt = origin + (direction * distance); + surfaceNormal = glm::normalize(hitAt - center); + } else { return false; } return true; @@ -297,9 +295,11 @@ bool ShapeEntityItem::findDetailedParabolaIntersection(const glm::vec3& origin, // NOTE: unit sphere has center of 0,0,0 and radius of 0.5 if (findParabolaSphereIntersection(entityFrameOrigin, entityFrameVelocity, entityFrameAcceleration, glm::vec3(0.0f), 0.5f, parabolicDistance)) { bool success; - // FIXME: this is only correct for uniformly scaled spheres - surfaceNormal = glm::normalize((origin + velocity * parabolicDistance + 0.5f * acceleration * parabolicDistance * parabolicDistance) - getCenterPosition(success)); - if (!success) { + glm::vec3 center = getCenterPosition(success); + if (success) { + // FIXME: this is only correct for uniformly scaled spheres + surfaceNormal = glm::normalize((origin + velocity * parabolicDistance + 0.5f * acceleration * parabolicDistance * parabolicDistance) - center); + } else { return false; } return true; diff --git a/libraries/octree/src/Octree.cpp b/libraries/octree/src/Octree.cpp index 9bb0e25982..c6474c1fe4 100644 --- a/libraries/octree/src/Octree.cpp +++ b/libraries/octree/src/Octree.cpp @@ -68,55 +68,12 @@ Octree::~Octree() { eraseAllOctreeElements(false); } - -// Inserts the value and key into three arrays sorted by the key array, the first array is the value, -// the second array is a sorted key for the value, the third array is the index for the value in it original -// non-sorted array -// returns -1 if size exceeded -// originalIndexArray is optional -int insertOctreeElementIntoSortedArrays(const OctreeElementPointer& value, float key, int originalIndex, - OctreeElementPointer* valueArray, float* keyArray, int* originalIndexArray, - int currentCount, int maxCount) { - - if (currentCount < maxCount) { - int i = 0; - if (currentCount > 0) { - while (i < currentCount && key > keyArray[i]) { - i++; - } - // i is our desired location - // shift array elements to the right - if (i < currentCount && i+1 < maxCount) { - for (int j = currentCount - 1; j > i; j--) { - valueArray[j] = valueArray[j - 1]; - keyArray[j] = keyArray[j - 1]; - } - } - } - // place new element at i - valueArray[i] = value; - keyArray[i] = key; - if (originalIndexArray) { - originalIndexArray[i] = originalIndex; - } - return currentCount + 1; - } - return -1; // error case -} - - - // Recurses voxel tree calling the RecurseOctreeOperation function for each element. // stops recursion if operation function returns false. void Octree::recurseTreeWithOperation(const RecurseOctreeOperation& operation, void* extraData) { recurseElementWithOperation(_rootElement, operation, extraData); } -// Recurses voxel tree calling the RecurseOctreePostFixOperation function for each element in post-fix order. -void Octree::recurseTreeWithPostOperation(const RecurseOctreeOperation& operation, void* extraData) { - recurseElementWithPostOperation(_rootElement, operation, extraData); -} - // Recurses voxel element with an operation function void Octree::recurseElementWithOperation(const OctreeElementPointer& element, const RecurseOctreeOperation& operation, void* extraData, int recursionCount) { @@ -129,71 +86,53 @@ void Octree::recurseElementWithOperation(const OctreeElementPointer& element, co for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { OctreeElementPointer child = element->getChildAtIndex(i); if (child) { - recurseElementWithOperation(child, operation, extraData, recursionCount+1); + recurseElementWithOperation(child, operation, extraData, recursionCount + 1); } } } } -// Recurses voxel element with an operation function -void Octree::recurseElementWithPostOperation(const OctreeElementPointer& element, const RecurseOctreeOperation& operation, - void* extraData, int recursionCount) { +void Octree::recurseTreeWithOperationSorted(const RecurseOctreeOperation& operation, const RecurseOctreeSortingOperation& sortingOperation, void* extraData) { + recurseElementWithOperationSorted(_rootElement, operation, sortingOperation, extraData); +} + +// Recurses voxel element with an operation function, calling operation on its children in a specific order +bool Octree::recurseElementWithOperationSorted(const OctreeElementPointer& element, const RecurseOctreeOperation& operation, + const RecurseOctreeSortingOperation& sortingOperation, void* extraData, int recursionCount) { if (recursionCount > DANGEROUSLY_DEEP_RECURSION) { - HIFI_FCDEBUG(octree(), "Octree::recurseElementWithPostOperation() reached DANGEROUSLY_DEEP_RECURSION, bailing!"); - return; + HIFI_FCDEBUG(octree(), "Octree::recurseElementWithOperationSorted() reached DANGEROUSLY_DEEP_RECURSION, bailing!"); + // If we go too deep, we want to keep searching other paths + return true; } + bool keepSearching = operation(element, extraData); + + std::vector sortedChildren; for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { OctreeElementPointer child = element->getChildAtIndex(i); if (child) { - recurseElementWithPostOperation(child, operation, extraData, recursionCount+1); - } - } - operation(element, extraData); -} - -// Recurses voxel tree calling the RecurseOctreeOperation function for each element. -// stops recursion if operation function returns false. -void Octree::recurseTreeWithOperationDistanceSorted(const RecurseOctreeOperation& operation, - const glm::vec3& point, void* extraData) { - - recurseElementWithOperationDistanceSorted(_rootElement, operation, point, extraData); -} - -// Recurses voxel element with an operation function -void Octree::recurseElementWithOperationDistanceSorted(const OctreeElementPointer& element, const RecurseOctreeOperation& operation, - const glm::vec3& point, void* extraData, int recursionCount) { - - if (recursionCount > DANGEROUSLY_DEEP_RECURSION) { - HIFI_FCDEBUG(octree(), "Octree::recurseElementWithOperationDistanceSorted() reached DANGEROUSLY_DEEP_RECURSION, bailing!"); - return; - } - - if (operation(element, extraData)) { - // determine the distance sorted order of our children - OctreeElementPointer sortedChildren[NUMBER_OF_CHILDREN] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; - float distancesToChildren[NUMBER_OF_CHILDREN] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - int indexOfChildren[NUMBER_OF_CHILDREN] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - int currentCount = 0; - - for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { - OctreeElementPointer childElement = element->getChildAtIndex(i); - if (childElement) { - // chance to optimize, doesn't need to be actual distance!! Could be distance squared - float distanceSquared = childElement->distanceSquareToPoint(point); - currentCount = insertOctreeElementIntoSortedArrays(childElement, distanceSquared, i, - sortedChildren, (float*)&distancesToChildren, - (int*)&indexOfChildren, currentCount, NUMBER_OF_CHILDREN); - } - } - - for (int i = 0; i < currentCount; i++) { - OctreeElementPointer childElement = sortedChildren[i]; - if (childElement) { - recurseElementWithOperationDistanceSorted(childElement, operation, point, extraData); + float priority = sortingOperation(child, extraData); + if (priority < FLT_MAX) { + sortedChildren.emplace_back(priority, child); } } } + + if (sortedChildren.size() > 1) { + static auto comparator = [](const SortedChild& left, const SortedChild& right) { return left.first > right.first; }; + std::sort(sortedChildren.begin(), sortedChildren.end(), comparator); + } + + for (auto it = sortedChildren.begin(); it != sortedChildren.end(); ++it) { + const SortedChild& sortedChild = *it; + // Our children were sorted, so if one hits something, we don't need to check the others + if (!recurseElementWithOperationSorted(sortedChild.second, operation, sortingOperation, extraData, recursionCount + 1)) { + return false; + } + } + // We checked all our children and didn't find anything. + // Stop if we hit something in this element. Continue if we didn't. + return keepSearching; } void Octree::recurseTreeWithOperator(RecurseOctreeOperator* operatorObject) { diff --git a/libraries/octree/src/Octree.h b/libraries/octree/src/Octree.h index b827ed7cd0..a2b2f227cb 100644 --- a/libraries/octree/src/Octree.h +++ b/libraries/octree/src/Octree.h @@ -49,6 +49,9 @@ public: // Callback function, for recuseTreeWithOperation using RecurseOctreeOperation = std::function; +// Function for sorting octree children during recursion. If return value == FLT_MAX, child is discarded +using RecurseOctreeSortingOperation = std::function; +using SortedChild = std::pair; typedef QHash CubeList; const bool NO_EXISTS_BITS = false; @@ -163,17 +166,10 @@ public: OctreeElementPointer getOrCreateChildElementContaining(const AACube& box); void recurseTreeWithOperation(const RecurseOctreeOperation& operation, void* extraData = NULL); - void recurseTreeWithPostOperation(const RecurseOctreeOperation& operation, void* extraData = NULL); - - /// \param operation type of operation - /// \param point point in world-frame (meters) - /// \param extraData hook for user data to be interpreted by special context - void recurseTreeWithOperationDistanceSorted(const RecurseOctreeOperation& operation, - const glm::vec3& point, void* extraData = NULL); + void recurseTreeWithOperationSorted(const RecurseOctreeOperation& operation, const RecurseOctreeSortingOperation& sortingOperation, void* extraData = NULL); void recurseTreeWithOperator(RecurseOctreeOperator* operatorObject); - bool isDirty() const { return _isDirty; } void clearDirtyBit() { _isDirty = false; } void setDirtyBit() { _isDirty = true; } @@ -227,14 +223,8 @@ public: void recurseElementWithOperation(const OctreeElementPointer& element, const RecurseOctreeOperation& operation, void* extraData, int recursionCount = 0); - - /// Traverse child nodes of node applying operation in post-fix order - /// - void recurseElementWithPostOperation(const OctreeElementPointer& element, const RecurseOctreeOperation& operation, - void* extraData, int recursionCount = 0); - - void recurseElementWithOperationDistanceSorted(const OctreeElementPointer& element, const RecurseOctreeOperation& operation, - const glm::vec3& point, void* extraData, int recursionCount = 0); + bool recurseElementWithOperationSorted(const OctreeElementPointer& element, const RecurseOctreeOperation& operation, + const RecurseOctreeSortingOperation& sortingOperation, void* extraData, int recursionCount = 0); bool recurseElementWithOperator(const OctreeElementPointer& element, RecurseOctreeOperator* operatorObject, int recursionCount = 0); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 8f4eb57f8e..22bc6b6ca7 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -379,14 +379,17 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g if (modelFrameBox.findRayIntersection(modelFrameOrigin, modelFrameDirection, distance, face, surfaceNormal)) { QMutexLocker locker(&_mutex); - float bestDistance = std::numeric_limits::max(); + float bestDistance = FLT_MAX; + BoxFace bestFace; Triangle bestModelTriangle; Triangle bestWorldTriangle; - int bestSubMeshIndex = 0; + glm::vec3 bestWorldIntersectionPoint; + glm::vec3 bestMeshIntersectionPoint; + int bestPartIndex; + int bestShapeID; + int bestSubMeshIndex; - int subMeshIndex = 0; const FBXGeometry& geometry = getFBXGeometry(); - if (!_triangleSetsValid) { calculateTriangleSets(geometry); } @@ -399,39 +402,75 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g glm::vec3 meshFrameDirection = glm::vec3(worldToMeshMatrix * glm::vec4(direction, 0.0f)); int shapeID = 0; + int subMeshIndex = 0; + + std::vector sortedTriangleSets; for (auto& meshTriangleSets : _modelSpaceMeshTriangleSets) { int partIndex = 0; - for (auto &partTriangleSet : meshTriangleSets) { - float triangleSetDistance; - BoxFace triangleSetFace; - Triangle triangleSetTriangle; - if (partTriangleSet.findRayIntersection(meshFrameOrigin, meshFrameDirection, triangleSetDistance, triangleSetFace, triangleSetTriangle, pickAgainstTriangles, allowBackface)) { - glm::vec3 meshIntersectionPoint = meshFrameOrigin + (meshFrameDirection * triangleSetDistance); - glm::vec3 worldIntersectionPoint = glm::vec3(meshToWorldMatrix * glm::vec4(meshIntersectionPoint, 1.0f)); - float worldDistance = glm::distance(origin, worldIntersectionPoint); - - if (worldDistance < bestDistance) { - bestDistance = worldDistance; - intersectedSomething = true; - face = triangleSetFace; - bestModelTriangle = triangleSetTriangle; - bestWorldTriangle = triangleSetTriangle * meshToWorldMatrix; - extraInfo["worldIntersectionPoint"] = vec3toVariant(worldIntersectionPoint); - extraInfo["meshIntersectionPoint"] = vec3toVariant(meshIntersectionPoint); - extraInfo["partIndex"] = partIndex; - extraInfo["shapeID"] = shapeID; - bestSubMeshIndex = subMeshIndex; + for (auto& partTriangleSet : meshTriangleSets) { + float priority = FLT_MAX; + if (partTriangleSet.getBounds().contains(meshFrameOrigin)) { + priority = 0.0f; + } else { + float partBoundDistance = FLT_MAX; + BoxFace partBoundFace; + glm::vec3 partBoundNormal; + if (partTriangleSet.getBounds().findRayIntersection(meshFrameOrigin, meshFrameDirection, partBoundDistance, + partBoundFace, partBoundNormal)) { + priority = partBoundDistance; } } + + if (priority < FLT_MAX) { + sortedTriangleSets.emplace_back(priority, &partTriangleSet, partIndex, shapeID, subMeshIndex); + } partIndex++; shapeID++; } subMeshIndex++; } + if (sortedTriangleSets.size() > 1) { + static auto comparator = [](const SortedTriangleSet& left, const SortedTriangleSet& right) { return left.distance > right.distance; }; + std::sort(sortedTriangleSets.begin(), sortedTriangleSets.end(), comparator); + } + + for (auto it = sortedTriangleSets.begin(); it != sortedTriangleSets.end(); ++it) { + const SortedTriangleSet& sortedTriangleSet = *it; + // We can exit once triangleSetDistance > bestDistance + if (sortedTriangleSet.distance > bestDistance) { + break; + } + float triangleSetDistance = FLT_MAX; + BoxFace triangleSetFace; + Triangle triangleSetTriangle; + if (sortedTriangleSet.triangleSet->findRayIntersection(meshFrameOrigin, meshFrameDirection, triangleSetDistance, triangleSetFace, + triangleSetTriangle, pickAgainstTriangles, allowBackface)) { + if (triangleSetDistance < bestDistance) { + bestDistance = triangleSetDistance; + intersectedSomething = true; + bestFace = triangleSetFace; + bestModelTriangle = triangleSetTriangle; + bestWorldTriangle = triangleSetTriangle * meshToWorldMatrix; + glm::vec3 meshIntersectionPoint = meshFrameOrigin + (meshFrameDirection * triangleSetDistance); + glm::vec3 worldIntersectionPoint = glm::vec3(meshToWorldMatrix * glm::vec4(meshIntersectionPoint, 1.0f)); + bestWorldIntersectionPoint = worldIntersectionPoint; + bestMeshIntersectionPoint = meshIntersectionPoint; + bestPartIndex = sortedTriangleSet.partIndex; + bestShapeID = sortedTriangleSet.shapeID; + bestSubMeshIndex = sortedTriangleSet.subMeshIndex; + } + } + } + if (intersectedSomething) { distance = bestDistance; + face = bestFace; surfaceNormal = bestWorldTriangle.getNormal(); + extraInfo["worldIntersectionPoint"] = vec3toVariant(bestWorldIntersectionPoint); + extraInfo["meshIntersectionPoint"] = vec3toVariant(bestMeshIntersectionPoint); + extraInfo["partIndex"] = bestPartIndex; + extraInfo["shapeID"] = bestShapeID; if (pickAgainstTriangles) { extraInfo["subMeshIndex"] = bestSubMeshIndex; extraInfo["subMeshName"] = geometry.getModelNameOfMesh(bestSubMeshIndex); @@ -483,13 +522,16 @@ bool Model::findParabolaIntersectionAgainstSubMeshes(const glm::vec3& origin, co QMutexLocker locker(&_mutex); float bestDistance = FLT_MAX; + BoxFace bestFace; Triangle bestModelTriangle; Triangle bestWorldTriangle; - int bestSubMeshIndex = 0; + glm::vec3 bestWorldIntersectionPoint; + glm::vec3 bestMeshIntersectionPoint; + int bestPartIndex; + int bestShapeID; + int bestSubMeshIndex; - int subMeshIndex = 0; const FBXGeometry& geometry = getFBXGeometry(); - if (!_triangleSetsValid) { calculateTriangleSets(geometry); } @@ -503,40 +545,79 @@ bool Model::findParabolaIntersectionAgainstSubMeshes(const glm::vec3& origin, co glm::vec3 meshFrameAcceleration = glm::vec3(worldToMeshMatrix * glm::vec4(acceleration, 0.0f)); int shapeID = 0; + int subMeshIndex = 0; + + std::vector sortedTriangleSets; for (auto& meshTriangleSets : _modelSpaceMeshTriangleSets) { int partIndex = 0; - for (auto &partTriangleSet : meshTriangleSets) { - float triangleSetDistance; - BoxFace triangleSetFace; - Triangle triangleSetTriangle; - if (partTriangleSet.findParabolaIntersection(meshFrameOrigin, meshFrameVelocity, meshFrameAcceleration, - triangleSetDistance, triangleSetFace, triangleSetTriangle, pickAgainstTriangles, allowBackface)) { - if (triangleSetDistance < bestDistance) { - bestDistance = triangleSetDistance; - intersectedSomething = true; - face = triangleSetFace; - bestModelTriangle = triangleSetTriangle; - bestWorldTriangle = triangleSetTriangle * meshToWorldMatrix; - glm::vec3 meshIntersectionPoint = meshFrameOrigin + meshFrameVelocity * triangleSetDistance + - 0.5f * meshFrameAcceleration * triangleSetDistance * triangleSetDistance; - glm::vec3 worldIntersectionPoint = origin + velocity * triangleSetDistance + - 0.5f * acceleration * triangleSetDistance * triangleSetDistance; - extraInfo["worldIntersectionPoint"] = vec3toVariant(worldIntersectionPoint); - extraInfo["meshIntersectionPoint"] = vec3toVariant(meshIntersectionPoint); - extraInfo["partIndex"] = partIndex; - extraInfo["shapeID"] = shapeID; - bestSubMeshIndex = subMeshIndex; + for (auto& partTriangleSet : meshTriangleSets) { + float priority = FLT_MAX; + if (partTriangleSet.getBounds().contains(meshFrameOrigin)) { + priority = 0.0f; + } else { + float partBoundDistance = FLT_MAX; + BoxFace partBoundFace; + glm::vec3 partBoundNormal; + if (partTriangleSet.getBounds().findParabolaIntersection(meshFrameOrigin, meshFrameVelocity, meshFrameAcceleration, + partBoundDistance, partBoundFace, partBoundNormal)) { + priority = partBoundDistance; } } + + if (priority < FLT_MAX) { + sortedTriangleSets.emplace_back(priority, &partTriangleSet, partIndex, shapeID, subMeshIndex); + } partIndex++; shapeID++; } subMeshIndex++; } + if (sortedTriangleSets.size() > 1) { + static auto comparator = [](const SortedTriangleSet& left, const SortedTriangleSet& right) { return left.distance > right.distance; }; + std::sort(sortedTriangleSets.begin(), sortedTriangleSets.end(), comparator); + } + + for (auto it = sortedTriangleSets.begin(); it != sortedTriangleSets.end(); ++it) { + const SortedTriangleSet& sortedTriangleSet = *it; + // We can exit once triangleSetDistance > bestDistance + if (sortedTriangleSet.distance > bestDistance) { + break; + } + float triangleSetDistance = FLT_MAX; + BoxFace triangleSetFace; + Triangle triangleSetTriangle; + if (sortedTriangleSet.triangleSet->findParabolaIntersection(meshFrameOrigin, meshFrameVelocity, meshFrameAcceleration, + triangleSetDistance, triangleSetFace, triangleSetTriangle, + pickAgainstTriangles, allowBackface)) { + if (triangleSetDistance < bestDistance) { + bestDistance = triangleSetDistance; + intersectedSomething = true; + bestFace = triangleSetFace; + bestModelTriangle = triangleSetTriangle; + bestWorldTriangle = triangleSetTriangle * meshToWorldMatrix; + glm::vec3 meshIntersectionPoint = meshFrameOrigin + meshFrameVelocity * triangleSetDistance + + 0.5f * meshFrameAcceleration * triangleSetDistance * triangleSetDistance; + glm::vec3 worldIntersectionPoint = origin + velocity * triangleSetDistance + + 0.5f * acceleration * triangleSetDistance * triangleSetDistance; + bestWorldIntersectionPoint = worldIntersectionPoint; + bestMeshIntersectionPoint = meshIntersectionPoint; + bestPartIndex = sortedTriangleSet.partIndex; + bestShapeID = sortedTriangleSet.shapeID; + bestSubMeshIndex = sortedTriangleSet.subMeshIndex; + // These sets can overlap, so we can't exit early if we find something + } + } + } + if (intersectedSomething) { parabolicDistance = bestDistance; + face = bestFace; surfaceNormal = bestWorldTriangle.getNormal(); + extraInfo["worldIntersectionPoint"] = vec3toVariant(bestWorldIntersectionPoint); + extraInfo["meshIntersectionPoint"] = vec3toVariant(bestMeshIntersectionPoint); + extraInfo["partIndex"] = bestPartIndex; + extraInfo["shapeID"] = bestShapeID; if (pickAgainstTriangles) { extraInfo["subMeshIndex"] = bestSubMeshIndex; extraInfo["subMeshName"] = geometry.getModelNameOfMesh(bestSubMeshIndex); diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 627e5fddab..adb2fcdd3d 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -64,6 +64,16 @@ class Model; using ModelPointer = std::shared_ptr; using ModelWeakPointer = std::weak_ptr; +struct SortedTriangleSet { + SortedTriangleSet(float distance, TriangleSet* triangleSet, int partIndex, int shapeID, int subMeshIndex) : + distance(distance), triangleSet(triangleSet), partIndex(partIndex), shapeID(shapeID), subMeshIndex(subMeshIndex) {} + + float distance; + TriangleSet* triangleSet; + int partIndex; + int shapeID; + int subMeshIndex; +}; /// A generic 3D model displaying geometry loaded from a URL. class Model : public QObject, public std::enable_shared_from_this, public scriptable::ModelProvider { diff --git a/libraries/shared/src/GeometryUtil.cpp b/libraries/shared/src/GeometryUtil.cpp index 6fb06eb624..a93c2ec9f3 100644 --- a/libraries/shared/src/GeometryUtil.cpp +++ b/libraries/shared/src/GeometryUtil.cpp @@ -286,12 +286,13 @@ bool findRaySphereIntersection(const glm::vec3& origin, const glm::vec3& directi distance = 0.0f; return true; // starts inside the sphere } - float b = glm::dot(direction, relativeOrigin); - float radicand = b * b - c; + float b = 2.0f * glm::dot(direction, relativeOrigin); + float a = glm::dot(direction, direction); + float radicand = b * b - 4.0f * a * c; if (radicand < 0.0f) { return false; // doesn't hit the sphere } - float t = -b - sqrtf(radicand); + float t = 0.5f * (-b - sqrtf(radicand)) / a; if (t < 0.0f) { return false; // doesn't hit the sphere } diff --git a/libraries/shared/src/TriangleSet.cpp b/libraries/shared/src/TriangleSet.cpp index cde9c20cab..f3c0ef5776 100644 --- a/libraries/shared/src/TriangleSet.cpp +++ b/libraries/shared/src/TriangleSet.cpp @@ -13,6 +13,8 @@ #include "GLMHelpers.h" +#include + void TriangleSet::insert(const Triangle& t) { _isBalanced = false; @@ -30,47 +32,6 @@ void TriangleSet::clear() { _triangleOctree.clear(); } -bool TriangleSet::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, - float& distance, BoxFace& face, Triangle& triangle, bool precision, bool allowBackface) { - - // reset our distance to be the max possible, lower level tests will store best distance here - distance = std::numeric_limits::max(); - - if (!_isBalanced) { - balanceOctree(); - } - - int trianglesTouched = 0; - auto result = _triangleOctree.findRayIntersection(origin, direction, distance, face, triangle, precision, trianglesTouched, allowBackface); - - #if WANT_DEBUGGING - if (precision) { - qDebug() << "trianglesTouched :" << trianglesTouched << "out of:" << _triangleOctree._population << "_triangles.size:" << _triangles.size(); - } - #endif - return result; -} - -bool TriangleSet::findParabolaIntersection(const glm::vec3& origin, const glm::vec3& velocity, const glm::vec3& acceleration, - float& parabolicDistance, BoxFace& face, Triangle& triangle, bool precision, bool allowBackface) { - // reset our distance to be the max possible, lower level tests will store best distance here - parabolicDistance = FLT_MAX; - - if (!_isBalanced) { - balanceOctree(); - } - - int trianglesTouched = 0; - auto result = _triangleOctree.findParabolaIntersection(origin, velocity, acceleration, parabolicDistance, face, triangle, precision, trianglesTouched, allowBackface); - -#if WANT_DEBUGGING - if (precision) { - qDebug() << "trianglesTouched :" << trianglesTouched << "out of:" << _triangleOctree._population << "_triangles.size:" << _triangles.size(); - } -#endif - return result; -} - bool TriangleSet::convexHullContains(const glm::vec3& point) const { if (!_bounds.contains(point)) { return false; @@ -97,7 +58,7 @@ void TriangleSet::debugDump() { } void TriangleSet::balanceOctree() { - _triangleOctree.reset(_bounds, 0); + _triangleOctree.reset(_bounds); // insert all the triangles for (size_t i = 0; i < _triangles.size(); i++) { @@ -106,79 +67,15 @@ void TriangleSet::balanceOctree() { _isBalanced = true; - #if WANT_DEBUGGING +#if WANT_DEBUGGING debugDump(); - #endif +#endif } - -// Determine of the given ray (origin/direction) in model space intersects with any triangles -// in the set. If an intersection occurs, the distance and surface normal will be provided. -bool TriangleSet::TriangleOctreeCell::findRayIntersectionInternal(const glm::vec3& origin, const glm::vec3& direction, - float& distance, BoxFace& face, Triangle& triangle, bool precision, - int& trianglesTouched, bool allowBackface) { - bool intersectedSomething = false; - float bestDistance = FLT_MAX; - - if (precision) { - for (const auto& triangleIndex : _triangleIndices) { - const auto& thisTriangle = _allTriangles[triangleIndex]; - float thisTriangleDistance; - trianglesTouched++; - if (findRayTriangleIntersection(origin, direction, thisTriangle, thisTriangleDistance, allowBackface)) { - if (thisTriangleDistance < bestDistance) { - bestDistance = thisTriangleDistance; - intersectedSomething = true; - triangle = thisTriangle; - } - } - } - } else { - intersectedSomething = true; - bestDistance = distance; - } - - if (intersectedSomething) { - distance = bestDistance; - } - - return intersectedSomething; -} - -bool TriangleSet::TriangleOctreeCell::findParabolaIntersectionInternal(const glm::vec3& origin, const glm::vec3& velocity, - const glm::vec3& acceleration, float& parabolicDistance, - BoxFace& face, Triangle& triangle, bool precision, - int& trianglesTouched, bool allowBackface) { - bool intersectedSomething = false; - float bestDistance = FLT_MAX; - - if (precision) { - for (const auto& triangleIndex : _triangleIndices) { - const auto& thisTriangle = _allTriangles[triangleIndex]; - float thisTriangleDistance; - trianglesTouched++; - if (findParabolaTriangleIntersection(origin, velocity, acceleration, thisTriangle, thisTriangleDistance, allowBackface)) { - if (thisTriangleDistance < bestDistance) { - bestDistance = thisTriangleDistance; - intersectedSomething = true; - triangle = thisTriangle; - } - } - } - } else { - intersectedSomething = true; - bestDistance = parabolicDistance; - } - - if (intersectedSomething) { - parabolicDistance = bestDistance; - } - - return intersectedSomething; -} - -static const int MAX_DEPTH = 4; // for now -static const int MAX_CHILDREN = 8; +// With an octree: 8 ^ MAX_DEPTH = 4096 leaves +//static const int MAX_DEPTH = 4; +// With a k-d tree: 2 ^ MAX_DEPTH = 4096 leaves +static const int MAX_DEPTH = 12; TriangleSet::TriangleOctreeCell::TriangleOctreeCell(std::vector& allTriangles, const AABox& bounds, int depth) : _allTriangles(allTriangles) @@ -190,7 +87,8 @@ void TriangleSet::TriangleOctreeCell::clear() { _population = 0; _triangleIndices.clear(); _bounds.clear(); - _children.clear(); + _children.first.reset(); + _children.second.reset(); } void TriangleSet::TriangleOctreeCell::reset(const AABox& bounds, int depth) { @@ -201,45 +99,76 @@ void TriangleSet::TriangleOctreeCell::reset(const AABox& bounds, int depth) { void TriangleSet::TriangleOctreeCell::debugDump() { qDebug() << __FUNCTION__; - qDebug() << "bounds:" << getBounds(); - qDebug() << "depth:" << _depth; - qDebug() << "population:" << _population << "this level or below" + qDebug() << " bounds:" << getBounds(); + qDebug() << " depth:" << _depth; + qDebug() << " population:" << _population << "this level or below" << " ---- triangleIndices:" << _triangleIndices.size() << "in this cell"; - qDebug() << "child cells:" << _children.size(); + int numChildren = 0; + if (_children.first) { + numChildren++; + } else if (_children.second) { + numChildren++; + } + qDebug() << "child cells:" << numChildren; if (_depth < MAX_DEPTH) { - int childNum = 0; - for (auto& child : _children) { - qDebug() << "child:" << childNum; - child.second.debugDump(); - childNum++; + if (_children.first) { + qDebug() << "child: 0"; + _children.first->debugDump(); + } + if (_children.second) { + qDebug() << "child: 1"; + _children.second->debugDump(); } } } +std::pair TriangleSet::TriangleOctreeCell::getTriangleOctreeCellChildBounds() { + std::pair toReturn; + int axis = 0; + // find biggest axis + glm::vec3 dimensions = _bounds.getDimensions(); + for (int i = 0; i < 3; i++) { + if (dimensions[i] >= dimensions[(i + 1) % 3] && dimensions[i] >= dimensions[(i + 2) % 3]) { + axis = i; + break; + } + } + + // The new boxes are half the size in the largest dimension + glm::vec3 newDimensions = dimensions; + newDimensions[axis] *= 0.5f; + toReturn.first.setBox(_bounds.getCorner(), newDimensions); + glm::vec3 offset = glm::vec3(0.0f); + offset[axis] = newDimensions[axis]; + toReturn.second.setBox(_bounds.getCorner() + offset, newDimensions); + return toReturn; +} + void TriangleSet::TriangleOctreeCell::insert(size_t triangleIndex) { - const Triangle& triangle = _allTriangles[triangleIndex]; _population++; + // if we're not yet at the max depth, then check which child the triangle fits in if (_depth < MAX_DEPTH) { + const Triangle& triangle = _allTriangles[triangleIndex]; + auto childBounds = getTriangleOctreeCellChildBounds(); - for (int child = 0; child < MAX_CHILDREN; child++) { - AABox childBounds = getBounds().getOctreeChild((AABox::OctreeChild)child); - - + auto insertOperator = [&](const AABox& childBound, std::shared_ptr& child) { // if the child AABox would contain the triangle... - if (childBounds.contains(triangle)) { + if (childBound.contains(triangle)) { // if the child cell doesn't yet exist, create it... - if (_children.find((AABox::OctreeChild)child) == _children.end()) { - _children.insert( - std::pair - ((AABox::OctreeChild)child, TriangleOctreeCell(_allTriangles, childBounds, _depth + 1))); + if (!child) { + child = std::make_shared(_allTriangles, childBound, _depth + 1); } // insert the triangleIndex in the child cell - _children.at((AABox::OctreeChild)child).insert(triangleIndex); - return; + child->insert(triangleIndex); + return true; } + return false; + }; + if (insertOperator(childBounds.first, _children.first) || insertOperator(childBounds.second, _children.second)) { + return; } } // either we're at max depth, or the triangle doesn't fit in one of our @@ -247,6 +176,62 @@ void TriangleSet::TriangleOctreeCell::insert(size_t triangleIndex) { _triangleIndices.push_back(triangleIndex); } +bool TriangleSet::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, + BoxFace& face, Triangle& triangle, bool precision, bool allowBackface) { + if (!_isBalanced) { + balanceOctree(); + } + + float localDistance = distance; + int trianglesTouched = 0; + bool hit = _triangleOctree.findRayIntersection(origin, direction, localDistance, face, triangle, precision, trianglesTouched, allowBackface); + if (hit) { + distance = localDistance; + } + +#if WANT_DEBUGGING + if (precision) { + qDebug() << "trianglesTouched :" << trianglesTouched << "out of:" << _triangleOctree._population << "_triangles.size:" << _triangles.size(); + } +#endif + return hit; +} + +// Determine of the given ray (origin/direction) in model space intersects with any triangles +// in the set. If an intersection occurs, the distance and surface normal will be provided. +bool TriangleSet::TriangleOctreeCell::findRayIntersectionInternal(const glm::vec3& origin, const glm::vec3& direction, + float& distance, BoxFace& face, Triangle& triangle, bool precision, + int& trianglesTouched, bool allowBackface) { + bool intersectedSomething = false; + float bestDistance = FLT_MAX; + Triangle bestTriangle; + + if (precision) { + for (const auto& triangleIndex : _triangleIndices) { + const auto& thisTriangle = _allTriangles[triangleIndex]; + float thisTriangleDistance; + trianglesTouched++; + if (findRayTriangleIntersection(origin, direction, thisTriangle, thisTriangleDistance, allowBackface)) { + if (thisTriangleDistance < bestDistance) { + bestDistance = thisTriangleDistance; + bestTriangle = thisTriangle; + intersectedSomething = true; + } + } + } + } else { + intersectedSomething = true; + bestDistance = distance; + } + + if (intersectedSomething) { + distance = bestDistance; + triangle = bestTriangle; + } + + return intersectedSomething; +} + bool TriangleSet::TriangleOctreeCell::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face, Triangle& triangle, bool precision, int& trianglesTouched, bool allowBackface) { @@ -257,52 +242,81 @@ bool TriangleSet::TriangleOctreeCell::findRayIntersection(const glm::vec3& origi float bestLocalDistance = FLT_MAX; BoxFace bestLocalFace; Triangle bestLocalTriangle; - glm::vec3 bestLocalNormal; bool intersects = false; - float boxDistance = FLT_MAX; - // if the pick intersects our bounding box, then continue - if (getBounds().findRayIntersection(origin, direction, boxDistance, bestLocalFace, bestLocalNormal)) { - // if the intersection with our bounding box, is greater than the current best distance (the distance passed in) - // then we know that none of our triangles can represent a better intersection and we can return - if (boxDistance > distance) { - return false; - } - - // if we're not yet at the max depth, then check which child the triangle fits in - if (_depth < MAX_DEPTH) { - float bestChildDistance = FLT_MAX; - for (auto& child : _children) { - // check each child, if there's an intersection, it will return some distance that we need - // to compare against the other results, because there might be multiple intersections and - // we will always choose the best (shortest) intersection - float childDistance = bestChildDistance; - BoxFace childFace; - Triangle childTriangle; - if (child.second.findRayIntersection(origin, direction, childDistance, childFace, childTriangle, precision, trianglesTouched)) { - if (childDistance < bestLocalDistance) { - bestLocalDistance = childDistance; - bestChildDistance = childDistance; - bestLocalFace = childFace; - bestLocalTriangle = childTriangle; - intersects = true; - } - } - } - } - // also check our local triangle set - float internalDistance = boxDistance; + // Check our local triangle set first + // The distance passed in here is the distance to our bounding box. If !precision, that distance is used + { + float internalDistance = distance; BoxFace internalFace; Triangle internalTriangle; if (findRayIntersectionInternal(origin, direction, internalDistance, internalFace, internalTriangle, precision, trianglesTouched, allowBackface)) { - if (internalDistance < bestLocalDistance) { - bestLocalDistance = internalDistance; - bestLocalFace = internalFace; - bestLocalTriangle = internalTriangle; - intersects = true; + bestLocalDistance = internalDistance; + bestLocalFace = internalFace; + bestLocalTriangle = internalTriangle; + intersects = true; + } + } + + // if we're not yet at the max depth, then check our children + if (_depth < MAX_DEPTH) { + std::list sortedTriangleCells; + auto sortingOperator = [&](std::shared_ptr& child) { + if (child) { + float priority = FLT_MAX; + if (child->getBounds().contains(origin)) { + priority = 0.0f; + } else { + float childBoundDistance = FLT_MAX; + BoxFace childBoundFace; + glm::vec3 childBoundNormal; + if (child->getBounds().findRayIntersection(origin, direction, childBoundDistance, childBoundFace, childBoundNormal)) { + // We only need to add this cell if it's closer than the local triangle set intersection (if there was one) + if (childBoundDistance < bestLocalDistance) { + priority = childBoundDistance; + } + } + } + + if (priority < FLT_MAX) { + if (sortedTriangleCells.size() > 0 && priority < sortedTriangleCells.front().first) { + sortedTriangleCells.emplace_front(priority, child); + } else { + sortedTriangleCells.emplace_back(priority, child); + } + } + } + }; + sortingOperator(_children.first); + sortingOperator(_children.second); + + for (auto it = sortedTriangleCells.begin(); it != sortedTriangleCells.end(); ++it) { + const SortedTriangleCell& sortedTriangleCell = *it; + float childDistance = sortedTriangleCell.first; + // We can exit once childDistance > bestLocalDistance + if (childDistance > bestLocalDistance) { + break; + } + // If we're inside the child cell and !precision, we need the actual distance to the cell bounds + if (!precision && childDistance < EPSILON) { + BoxFace childBoundFace; + glm::vec3 childBoundNormal; + sortedTriangleCell.second->getBounds().findRayIntersection(origin, direction, childDistance, childBoundFace, childBoundNormal); + } + BoxFace childFace; + Triangle childTriangle; + if (sortedTriangleCell.second->findRayIntersection(origin, direction, childDistance, childFace, childTriangle, precision, trianglesTouched)) { + if (childDistance < bestLocalDistance) { + bestLocalDistance = childDistance; + bestLocalFace = childFace; + bestLocalTriangle = childTriangle; + intersects = true; + break; + } } } } + if (intersects) { distance = bestLocalDistance; face = bestLocalFace; @@ -311,6 +325,61 @@ bool TriangleSet::TriangleOctreeCell::findRayIntersection(const glm::vec3& origi return intersects; } +bool TriangleSet::findParabolaIntersection(const glm::vec3& origin, const glm::vec3& velocity, const glm::vec3& acceleration, + float& parabolicDistance, BoxFace& face, Triangle& triangle, bool precision, bool allowBackface) { + if (!_isBalanced) { + balanceOctree(); + } + + float localDistance = parabolicDistance; + int trianglesTouched = 0; + bool hit = _triangleOctree.findParabolaIntersection(origin, velocity, acceleration, localDistance, face, triangle, precision, trianglesTouched, allowBackface); + if (hit) { + parabolicDistance = localDistance; + } + +#if WANT_DEBUGGING + if (precision) { + qDebug() << "trianglesTouched :" << trianglesTouched << "out of:" << _triangleOctree._population << "_triangles.size:" << _triangles.size(); + } +#endif + return hit; +} + +bool TriangleSet::TriangleOctreeCell::findParabolaIntersectionInternal(const glm::vec3& origin, const glm::vec3& velocity, + const glm::vec3& acceleration, float& parabolicDistance, + BoxFace& face, Triangle& triangle, bool precision, + int& trianglesTouched, bool allowBackface) { + bool intersectedSomething = false; + float bestDistance = FLT_MAX; + Triangle bestTriangle; + + if (precision) { + for (const auto& triangleIndex : _triangleIndices) { + const auto& thisTriangle = _allTriangles[triangleIndex]; + float thisTriangleDistance; + trianglesTouched++; + if (findParabolaTriangleIntersection(origin, velocity, acceleration, thisTriangle, thisTriangleDistance, allowBackface)) { + if (thisTriangleDistance < bestDistance) { + bestDistance = thisTriangleDistance; + bestTriangle = thisTriangle; + intersectedSomething = true; + } + } + } + } else { + intersectedSomething = true; + bestDistance = parabolicDistance; + } + + if (intersectedSomething) { + parabolicDistance = bestDistance; + triangle = bestTriangle; + } + + return intersectedSomething; +} + bool TriangleSet::TriangleOctreeCell::findParabolaIntersection(const glm::vec3& origin, const glm::vec3& velocity, const glm::vec3& acceleration, float& parabolicDistance, BoxFace& face, Triangle& triangle, bool precision, @@ -322,52 +391,81 @@ bool TriangleSet::TriangleOctreeCell::findParabolaIntersection(const glm::vec3& float bestLocalDistance = FLT_MAX; BoxFace bestLocalFace; Triangle bestLocalTriangle; - glm::vec3 bestLocalNormal; bool intersects = false; - float boxDistance = FLT_MAX; - // if the pick intersects our bounding box, then continue - if (getBounds().findParabolaIntersection(origin, velocity, acceleration, boxDistance, bestLocalFace, bestLocalNormal)) { - // if the intersection with our bounding box, is greater than the current best distance (the distance passed in) - // then we know that none of our triangles can represent a better intersection and we can return - if (boxDistance > parabolicDistance) { - return false; - } - - // if we're not yet at the max depth, then check which child the triangle fits in - if (_depth < MAX_DEPTH) { - float bestChildDistance = FLT_MAX; - for (auto& child : _children) { - // check each child, if there's an intersection, it will return some distance that we need - // to compare against the other results, because there might be multiple intersections and - // we will always choose the best (shortest) intersection - float childDistance = bestChildDistance; - BoxFace childFace; - Triangle childTriangle; - if (child.second.findParabolaIntersection(origin, velocity, acceleration, childDistance, childFace, childTriangle, precision, trianglesTouched)) { - if (childDistance < bestLocalDistance) { - bestLocalDistance = childDistance; - bestChildDistance = childDistance; - bestLocalFace = childFace; - bestLocalTriangle = childTriangle; - intersects = true; - } - } - } - } - // also check our local triangle set - float internalDistance = boxDistance; + // Check our local triangle set first + // The distance passed in here is the distance to our bounding box. If !precision, that distance is used + { + float internalDistance = parabolicDistance; BoxFace internalFace; Triangle internalTriangle; if (findParabolaIntersectionInternal(origin, velocity, acceleration, internalDistance, internalFace, internalTriangle, precision, trianglesTouched, allowBackface)) { - if (internalDistance < bestLocalDistance) { - bestLocalDistance = internalDistance; - bestLocalFace = internalFace; - bestLocalTriangle = internalTriangle; - intersects = true; + bestLocalDistance = internalDistance; + bestLocalFace = internalFace; + bestLocalTriangle = internalTriangle; + intersects = true; + } + } + + // if we're not yet at the max depth, then check our children + if (_depth < MAX_DEPTH) { + std::list sortedTriangleCells; + auto sortingOperator = [&](std::shared_ptr& child) { + if (child) { + float priority = FLT_MAX; + if (child->getBounds().contains(origin)) { + priority = 0.0f; + } else { + float childBoundDistance = FLT_MAX; + BoxFace childBoundFace; + glm::vec3 childBoundNormal; + if (child->getBounds().findParabolaIntersection(origin, velocity, acceleration, childBoundDistance, childBoundFace, childBoundNormal)) { + // We only need to add this cell if it's closer than the local triangle set intersection (if there was one) + if (childBoundDistance < bestLocalDistance) { + priority = childBoundDistance; + } + } + } + + if (priority < FLT_MAX) { + if (sortedTriangleCells.size() > 0 && priority < sortedTriangleCells.front().first) { + sortedTriangleCells.emplace_front(priority, child); + } else { + sortedTriangleCells.emplace_back(priority, child); + } + } + } + }; + sortingOperator(_children.first); + sortingOperator(_children.second); + + for (auto it = sortedTriangleCells.begin(); it != sortedTriangleCells.end(); ++it) { + const SortedTriangleCell& sortedTriangleCell = *it; + float childDistance = sortedTriangleCell.first; + // We can exit once childDistance > bestLocalDistance + if (childDistance > bestLocalDistance) { + break; + } + // If we're inside the child cell and !precision, we need the actual distance to the cell bounds + if (!precision && childDistance < EPSILON) { + BoxFace childBoundFace; + glm::vec3 childBoundNormal; + sortedTriangleCell.second->getBounds().findParabolaIntersection(origin, velocity, acceleration, childDistance, childBoundFace, childBoundNormal); + } + BoxFace childFace; + Triangle childTriangle; + if (sortedTriangleCell.second->findParabolaIntersection(origin, velocity, acceleration, childDistance, childFace, childTriangle, precision, trianglesTouched)) { + if (childDistance < bestLocalDistance) { + bestLocalDistance = childDistance; + bestLocalFace = childFace; + bestLocalTriangle = childTriangle; + intersects = true; + break; + } } } } + if (intersects) { parabolicDistance = bestLocalDistance; face = bestLocalFace; diff --git a/libraries/shared/src/TriangleSet.h b/libraries/shared/src/TriangleSet.h index 0b0d0a9ac5..a838e2d9e2 100644 --- a/libraries/shared/src/TriangleSet.h +++ b/libraries/shared/src/TriangleSet.h @@ -12,6 +12,7 @@ #pragma once #include +#include #include "AABox.h" #include "GeometryUtil.h" @@ -20,9 +21,8 @@ class TriangleSet { class TriangleOctreeCell { public: - TriangleOctreeCell(std::vector& allTriangles) : - _allTriangles(allTriangles) - { } + TriangleOctreeCell(std::vector& allTriangles) : _allTriangles(allTriangles) {} + TriangleOctreeCell(std::vector& allTriangles, const AABox& bounds, int depth); void insert(size_t triangleIndex); void reset(const AABox& bounds, int depth = 0); @@ -40,8 +40,6 @@ class TriangleSet { void debugDump(); protected: - TriangleOctreeCell(std::vector& allTriangles, const AABox& bounds, int depth); - // checks our internal list of triangles bool findRayIntersectionInternal(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face, Triangle& triangle, bool precision, int& trianglesTouched, @@ -50,20 +48,22 @@ class TriangleSet { float& parabolicDistance, BoxFace& face, Triangle& triangle, bool precision, int& trianglesTouched, bool allowBackface = false); + std::pair getTriangleOctreeCellChildBounds(); + std::vector& _allTriangles; - std::map _children; - int _depth{ 0 }; - int _population{ 0 }; + std::pair, std::shared_ptr> _children; + int _depth { 0 }; + int _population { 0 }; AABox _bounds; std::vector _triangleIndices; friend class TriangleSet; }; + using SortedTriangleCell = std::pair>; + public: - TriangleSet() : - _triangleOctree(_triangles) - {} + TriangleSet() : _triangleOctree(_triangles) {} void debugDump(); @@ -87,8 +87,7 @@ public: const AABox& getBounds() const { return _bounds; } protected: - - bool _isBalanced{ false }; + bool _isBalanced { false }; std::vector _triangles; TriangleOctreeCell _triangleOctree; AABox _bounds; From db8e1bdfa34610031d9dd6ca8aa86bd15fb275af Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Wed, 22 Aug 2018 16:47:18 -0700 Subject: [PATCH 073/545] compile error fix --- interface/src/Application.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index cc8736a481..6b2781417d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2258,8 +2258,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo if (_avatarOverrideUrl.isValid()) { getMyAvatar()->useFullAvatarURL(_avatarOverrideUrl); } - static const QUrl empty{}; - if (getMyAvatar()->getFullAvatarURLFromPreferences() != getMyAvatar()->cannonicalSkeletonModelURL(empty)) { + + if (getMyAvatar()->getFullAvatarURLFromPreferences() != getMyAvatar()->getSkeletonModelURL()) { getMyAvatar()->resetFullAvatarURL(); } getMyAvatar()->markIdentityDataChanged(); From bb83a2f620955a56d8ccdf30d218dc3066fe6bff Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Wed, 22 Aug 2018 16:48:10 -0700 Subject: [PATCH 074/545] interstitial script ending cleanup fixes --- scripts/system/interstitialPage.js | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/system/interstitialPage.js b/scripts/system/interstitialPage.js index 3f1fc58b55..1507c7bd9a 100644 --- a/scripts/system/interstitialPage.js +++ b/scripts/system/interstitialPage.js @@ -431,6 +431,7 @@ renderViewTask.getConfig("LightingModel")["enableAmbientLight"] = true; renderViewTask.getConfig("LightingModel")["enableDirectionalLight"] = true; renderViewTask.getConfig("LightingModel")["enablePointLight"] = true; + toolbar.writeProperty("visible", true); } Script.scriptEnding.connect(cleanup); From 8c422cb0ebf6f29ff90682eb1431f5b44357b717 Mon Sep 17 00:00:00 2001 From: David Back Date: Wed, 22 Aug 2018 16:54:59 -0700 Subject: [PATCH 075/545] change corner cubes to center cube, replace spheres with cubes --- .../system/libraries/entitySelectionTool.js | 362 +++++++----------- 1 file changed, 134 insertions(+), 228 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index 1c7d5244a1..bc36024e07 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -433,14 +433,14 @@ SelectionDisplay = (function() { var ROTATE_DISPLAY_SIZE_Y_MULTIPLIER = 0.09; var ROTATE_DISPLAY_LINE_HEIGHT_MULTIPLIER = 0.07; - var STRETCH_SPHERE_OFFSET = 0.06; - var STRETCH_SPHERE_CAMERA_DISTANCE_MULTIPLE = 0.01; + var STRETCH_CUBE_OFFSET = 0.06; + var STRETCH_CUBE_CAMERA_DISTANCE_MULTIPLE = 0.02; var STRETCH_MINIMUM_DIMENSION = 0.001; var STRETCH_ALL_MINIMUM_DIMENSION = 0.01; var STRETCH_DIRECTION_ALL_CAMERA_DISTANCE_MULTIPLE = 6; var STRETCH_PANEL_WIDTH = 0.01; - var SCALE_CUBE_OFFSET = 0.5; + var SCALE_EDGE_OFFSET = 0.5; var SCALE_CUBE_CAMERA_DISTANCE_MULTIPLE = 0.0125; var CLONER_OFFSET = { x: 0.9, y: -0.9, z: 0.9 }; @@ -589,20 +589,18 @@ SelectionDisplay = (function() { leftMargin: 0 }); - var handlePropertiesStretchSpheres = { - alpha: 1, - shape: "Sphere", + var handlePropertiesStretchCubes = { solid: true, visible: false, ignoreRayIntersection: false, drawInFront: true }; - var handleStretchXSphere = Overlays.addOverlay("shape", handlePropertiesStretchSpheres); - Overlays.editOverlay(handleStretchXSphere, { color: COLOR_RED }); - var handleStretchYSphere = Overlays.addOverlay("shape", handlePropertiesStretchSpheres); - Overlays.editOverlay(handleStretchYSphere, { color: COLOR_GREEN }); - var handleStretchZSphere = Overlays.addOverlay("shape", handlePropertiesStretchSpheres); - Overlays.editOverlay(handleStretchZSphere, { color: COLOR_BLUE }); + var handleStretchXCube = Overlays.addOverlay("cube", handlePropertiesStretchCubes); + Overlays.editOverlay(handleStretchXCube, { color: COLOR_RED }); + var handleStretchYCube = Overlays.addOverlay("cube", handlePropertiesStretchCubes); + Overlays.editOverlay(handleStretchYCube, { color: COLOR_GREEN }); + var handleStretchZCube = Overlays.addOverlay("cube", handlePropertiesStretchCubes); + Overlays.editOverlay(handleStretchZCube, { color: COLOR_BLUE }); var handlePropertiesStretchPanel = { shape: "Quad", @@ -619,8 +617,7 @@ SelectionDisplay = (function() { var handleStretchZPanel = Overlays.addOverlay("shape", handlePropertiesStretchPanel); Overlays.editOverlay(handleStretchZPanel, { color: COLOR_BLUE }); - var handlePropertiesScaleCubes = { - alpha: 1, + var handleScaleCube = Overlays.addOverlay("cube", { size: 0.025, color: COLOR_SCALE_CUBE, solid: true, @@ -628,15 +625,7 @@ SelectionDisplay = (function() { ignoreRayIntersection: false, drawInFront: true, borderSize: 1.4 - }; - var handleScaleLBNCube = Overlays.addOverlay("cube", handlePropertiesScaleCubes); // (-x, -y, -z) - var handleScaleRBNCube = Overlays.addOverlay("cube", handlePropertiesScaleCubes); // ( x, -y, -z) - var handleScaleLBFCube = Overlays.addOverlay("cube", handlePropertiesScaleCubes); // (-x, -y, z) - var handleScaleRBFCube = Overlays.addOverlay("cube", handlePropertiesScaleCubes); // ( x, -y, z) - var handleScaleLTNCube = Overlays.addOverlay("cube", handlePropertiesScaleCubes); // (-x, y, -z) - var handleScaleRTNCube = Overlays.addOverlay("cube", handlePropertiesScaleCubes); // ( x, y, -z) - var handleScaleLTFCube = Overlays.addOverlay("cube", handlePropertiesScaleCubes); // (-x, y, z) - var handleScaleRTFCube = Overlays.addOverlay("cube", handlePropertiesScaleCubes); // ( x, y, z) + }); var handlePropertiesScaleEdge = { alpha: 1, @@ -738,20 +727,13 @@ SelectionDisplay = (function() { handleRotateRollRing, handleRotateCurrentRing, rotationDegreesDisplay, - handleStretchXSphere, - handleStretchYSphere, - handleStretchZSphere, + handleStretchXCube, + handleStretchYCube, + handleStretchZCube, handleStretchXPanel, handleStretchYPanel, handleStretchZPanel, - handleScaleLBNCube, - handleScaleRBNCube, - handleScaleLBFCube, - handleScaleRBFCube, - handleScaleLTNCube, - handleScaleRTNCube, - handleScaleLTFCube, - handleScaleRTFCube, + handleScaleCube, handleScaleTREdge, handleScaleTLEdge, handleScaleTFEdge, @@ -787,21 +769,14 @@ SelectionDisplay = (function() { overlayNames[handleRotateCurrentRing] = "handleRotateCurrentRing"; overlayNames[rotationDegreesDisplay] = "rotationDegreesDisplay"; - overlayNames[handleStretchXSphere] = "handleStretchXSphere"; - overlayNames[handleStretchYSphere] = "handleStretchYSphere"; - overlayNames[handleStretchZSphere] = "handleStretchZSphere"; + overlayNames[handleStretchXCube] = "handleStretchXCube"; + overlayNames[handleStretchYCube] = "handleStretchYCube"; + overlayNames[handleStretchZCube] = "handleStretchZCube"; overlayNames[handleStretchXPanel] = "handleStretchXPanel"; overlayNames[handleStretchYPanel] = "handleStretchYPanel"; overlayNames[handleStretchZPanel] = "handleStretchZPanel"; - overlayNames[handleScaleLBNCube] = "handleScaleLBNCube"; - overlayNames[handleScaleRBNCube] = "handleScaleRBNCube"; - overlayNames[handleScaleLBFCube] = "handleScaleLBFCube"; - overlayNames[handleScaleRBFCube] = "handleScaleRBFCube"; - overlayNames[handleScaleLTNCube] = "handleScaleLTNCube"; - overlayNames[handleScaleRTNCube] = "handleScaleRTNCube"; - overlayNames[handleScaleLTFCube] = "handleScaleLTFCube"; - overlayNames[handleScaleRTFCube] = "handleScaleRTFCube"; + overlayNames[handleScaleCube] = "handleScaleCube"; overlayNames[handleScaleTREdge] = "handleScaleTREdge"; overlayNames[handleScaleTLEdge] = "handleScaleTLEdge"; @@ -1021,32 +996,25 @@ SelectionDisplay = (function() { case handleTranslateXCone: case handleTranslateXCylinder: case handleRotatePitchRing: - case handleStretchXSphere: + case handleStretchXCube: pickedColor = COLOR_RED; highlightNeeded = true; break; case handleTranslateYCone: case handleTranslateYCylinder: case handleRotateYawRing: - case handleStretchYSphere: + case handleStretchYCube: pickedColor = COLOR_GREEN; highlightNeeded = true; break; case handleTranslateZCone: case handleTranslateZCylinder: case handleRotateRollRing: - case handleStretchZSphere: + case handleStretchZCube: pickedColor = COLOR_BLUE; highlightNeeded = true; break; - case handleScaleLBNCube: - case handleScaleRBNCube: - case handleScaleLBFCube: - case handleScaleRBFCube: - case handleScaleLTNCube: - case handleScaleRTNCube: - case handleScaleLTFCube: - case handleScaleRTFCube: + case handleScaleCube: pickedColor = COLOR_SCALE_CUBE; highlightNeeded = true; break; @@ -1424,127 +1392,83 @@ SelectionDisplay = (function() { dimensions: arrowConeDimensions }); - // UPDATE SCALE CUBES - var scaleCubeOffsetX = SCALE_CUBE_OFFSET * dimensions.x; - var scaleCubeOffsetY = SCALE_CUBE_OFFSET * dimensions.y; - var scaleCubeOffsetZ = SCALE_CUBE_OFFSET * dimensions.z; - var scaleCubeRotation = spaceMode === SPACE_LOCAL ? rotation : Quat.IDENTITY; - var scaleLBNCubePosition = { x: -scaleCubeOffsetX, y: -scaleCubeOffsetY, z: -scaleCubeOffsetZ }; - scaleLBNCubePosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, scaleLBNCubePosition)); - var scaleLBNCubeToCamera = getDistanceToCamera(scaleLBNCubePosition); - var scaleRBNCubePosition = { x: scaleCubeOffsetX, y: -scaleCubeOffsetY, z: -scaleCubeOffsetZ }; - scaleRBNCubePosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, scaleRBNCubePosition)); - var scaleRBNCubeToCamera = getDistanceToCamera(scaleRBNCubePosition); - var scaleLBFCubePosition = { x: -scaleCubeOffsetX, y: -scaleCubeOffsetY, z: scaleCubeOffsetZ }; - scaleLBFCubePosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, scaleLBFCubePosition)); - var scaleLBFCubeToCamera = getDistanceToCamera(scaleLBFCubePosition); - var scaleRBFCubePosition = { x: scaleCubeOffsetX, y: -scaleCubeOffsetY, z: scaleCubeOffsetZ }; - scaleRBFCubePosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, scaleRBFCubePosition)); - var scaleRBFCubeToCamera = getDistanceToCamera(scaleRBFCubePosition); - var scaleLTNCubePosition = { x: -scaleCubeOffsetX, y: scaleCubeOffsetY, z: -scaleCubeOffsetZ }; - scaleLTNCubePosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, scaleLTNCubePosition)); - var scaleLTNCubeToCamera = getDistanceToCamera(scaleLTNCubePosition); - var scaleRTNCubePosition = { x: scaleCubeOffsetX, y: scaleCubeOffsetY, z: -scaleCubeOffsetZ }; - scaleRTNCubePosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, scaleRTNCubePosition)); - var scaleRTNCubeToCamera = getDistanceToCamera(scaleRTNCubePosition); - var scaleLTFCubePosition = { x: -scaleCubeOffsetX, y: scaleCubeOffsetY, z: scaleCubeOffsetZ }; - scaleLTFCubePosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, scaleLTFCubePosition)); - var scaleLTFCubeToCamera = getDistanceToCamera(scaleLTFCubePosition); - var scaleRTFCubePosition = { x: scaleCubeOffsetX, y: scaleCubeOffsetY, z: scaleCubeOffsetZ }; - scaleRTFCubePosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, scaleRTFCubePosition)); - var scaleRTFCubeToCamera = getDistanceToCamera(scaleRTFCubePosition); - - var scaleCubeToCamera = Math.min(scaleLBNCubeToCamera, scaleRBNCubeToCamera, scaleLBFCubeToCamera, - scaleRBFCubeToCamera, scaleLTNCubeToCamera, scaleRTNCubeToCamera, - scaleLTFCubeToCamera, scaleRTFCubeToCamera); - var scaleCubeDimension = scaleCubeToCamera * SCALE_CUBE_CAMERA_DISTANCE_MULTIPLE; + // UPDATE SCALE CUBE + var scaleCubeRotation = spaceMode === SPACE_LOCAL ? rotation : Quat.IDENTITY; + var scaleCubeDimension = rotateDimension * SCALE_CUBE_CAMERA_DISTANCE_MULTIPLE / + ROTATE_RING_CAMERA_DISTANCE_MULTIPLE; var scaleCubeDimensions = { x: scaleCubeDimension, y: scaleCubeDimension, z: scaleCubeDimension }; - - Overlays.editOverlay(handleScaleLBNCube, { - position: scaleLBNCubePosition, - rotation: scaleCubeRotation, - dimensions: scaleCubeDimensions - }); - Overlays.editOverlay(handleScaleRBNCube, { - position: scaleRBNCubePosition, - rotation: scaleCubeRotation, - dimensions: scaleCubeDimensions - }); - Overlays.editOverlay(handleScaleLBFCube, { - position: scaleLBFCubePosition, - rotation: scaleCubeRotation, - dimensions: scaleCubeDimensions - }); - Overlays.editOverlay(handleScaleRBFCube, { - position: scaleRBFCubePosition, - rotation: scaleCubeRotation, - dimensions: scaleCubeDimensions - }); - Overlays.editOverlay(handleScaleLTNCube, { - position: scaleLTNCubePosition, - rotation: scaleCubeRotation, - dimensions: scaleCubeDimensions - }); - Overlays.editOverlay(handleScaleRTNCube, { - position: scaleRTNCubePosition, - rotation: scaleCubeRotation, - dimensions: scaleCubeDimensions - }); - Overlays.editOverlay(handleScaleLTFCube, { - position: scaleLTFCubePosition, - rotation: scaleCubeRotation, - dimensions: scaleCubeDimensions - }); - Overlays.editOverlay(handleScaleRTFCube, { - position: scaleRTFCubePosition, + Overlays.editOverlay(handleScaleCube, { + position: position, rotation: scaleCubeRotation, dimensions: scaleCubeDimensions }); // UPDATE SCALE EDGES - Overlays.editOverlay(handleScaleTREdge, { start: scaleRTNCubePosition, end: scaleRTFCubePosition }); - Overlays.editOverlay(handleScaleTLEdge, { start: scaleLTNCubePosition, end: scaleLTFCubePosition }); - Overlays.editOverlay(handleScaleTFEdge, { start: scaleLTFCubePosition, end: scaleRTFCubePosition }); - Overlays.editOverlay(handleScaleTNEdge, { start: scaleLTNCubePosition, end: scaleRTNCubePosition }); - Overlays.editOverlay(handleScaleBREdge, { start: scaleRBNCubePosition, end: scaleRBFCubePosition }); - Overlays.editOverlay(handleScaleBLEdge, { start: scaleLBNCubePosition, end: scaleLBFCubePosition }); - Overlays.editOverlay(handleScaleBFEdge, { start: scaleLBFCubePosition, end: scaleRBFCubePosition }); - Overlays.editOverlay(handleScaleBNEdge, { start: scaleLBNCubePosition, end: scaleRBNCubePosition }); - Overlays.editOverlay(handleScaleNREdge, { start: scaleRTNCubePosition, end: scaleRBNCubePosition }); - Overlays.editOverlay(handleScaleNLEdge, { start: scaleLTNCubePosition, end: scaleLBNCubePosition }); - Overlays.editOverlay(handleScaleFREdge, { start: scaleRTFCubePosition, end: scaleRBFCubePosition }); - Overlays.editOverlay(handleScaleFLEdge, { start: scaleLTFCubePosition, end: scaleLBFCubePosition }); + var edgeOffsetX = SCALE_EDGE_OFFSET * dimensions.x; + var edgeOffsetY = SCALE_EDGE_OFFSET * dimensions.y; + var edgeOffsetZ = SCALE_EDGE_OFFSET * dimensions.z; + var LBNPosition = { x: -edgeOffsetX, y: -edgeOffsetY, z: -edgeOffsetZ }; + LBNPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, LBNPosition)); + var RBNPosition = { x: edgeOffsetX, y: -edgeOffsetY, z: -edgeOffsetZ }; + RBNPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, RBNPosition)); + var LBFPosition = { x: -edgeOffsetX, y: -edgeOffsetY, z: edgeOffsetZ }; + LBFPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, LBFPosition)); + var RBFPosition = { x: edgeOffsetX, y: -edgeOffsetY, z: edgeOffsetZ }; + RBFPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, RBFPosition)); + var LTNPosition = { x: -edgeOffsetX, y: edgeOffsetY, z: -edgeOffsetZ }; + LTNPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, LTNPosition)); + var RTNPosition = { x: edgeOffsetX, y: edgeOffsetY, z: -edgeOffsetZ }; + RTNPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, RTNPosition)); + var LTFPosition = { x: -edgeOffsetX, y: edgeOffsetY, z: edgeOffsetZ }; + LTFPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, LTFPosition)); + var RTFPosition = { x: edgeOffsetX, y: edgeOffsetY, z: edgeOffsetZ }; + RTFPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, RTFPosition)); + Overlays.editOverlay(handleScaleTREdge, { start: RTNPosition, end: RTFPosition }); + Overlays.editOverlay(handleScaleTLEdge, { start: LTNPosition, end: LTFPosition }); + Overlays.editOverlay(handleScaleTFEdge, { start: LTFPosition, end: RTFPosition }); + Overlays.editOverlay(handleScaleTNEdge, { start: LTNPosition, end: RTNPosition }); + Overlays.editOverlay(handleScaleBREdge, { start: RBNPosition, end: RBFPosition }); + Overlays.editOverlay(handleScaleBLEdge, { start: LBNPosition, end: LBFPosition }); + Overlays.editOverlay(handleScaleBFEdge, { start: LBFPosition, end: RBFPosition }); + Overlays.editOverlay(handleScaleBNEdge, { start: LBNPosition, end: RBNPosition }); + Overlays.editOverlay(handleScaleNREdge, { start: RTNPosition, end: RBNPosition }); + Overlays.editOverlay(handleScaleNLEdge, { start: LTNPosition, end: LBNPosition }); + Overlays.editOverlay(handleScaleFREdge, { start: RTFPosition, end: RBFPosition }); + Overlays.editOverlay(handleScaleFLEdge, { start: LTFPosition, end: LBFPosition }); - // UPDATE STRETCH SPHERES - var stretchSphereDimension = rotateDimension * STRETCH_SPHERE_CAMERA_DISTANCE_MULTIPLE / + // UPDATE STRETCH CUBES + var stretchCubeDimension = rotateDimension * STRETCH_CUBE_CAMERA_DISTANCE_MULTIPLE / ROTATE_RING_CAMERA_DISTANCE_MULTIPLE; - var stretchSphereDimensions = { x: stretchSphereDimension, y: stretchSphereDimension, z: stretchSphereDimension }; - var stretchSphereOffset = rotateDimension * STRETCH_SPHERE_OFFSET / ROTATE_RING_CAMERA_DISTANCE_MULTIPLE; - var stretchXPosition = { x: stretchSphereOffset, y: 0, z: 0 }; + var stretchCubeDimensions = { x: stretchCubeDimension, y: stretchCubeDimension, z: stretchCubeDimension }; + var stretchCubeOffset = rotateDimension * STRETCH_CUBE_OFFSET / ROTATE_RING_CAMERA_DISTANCE_MULTIPLE; + var stretchXPosition = { x: stretchCubeOffset, y: 0, z: 0 }; stretchXPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, stretchXPosition)); - Overlays.editOverlay(handleStretchXSphere, { + Overlays.editOverlay(handleStretchXCube, { position: stretchXPosition, - dimensions: stretchSphereDimensions + rotation: rotationX, + dimensions: stretchCubeDimensions }); - var stretchYPosition = { x: 0, y: stretchSphereOffset, z: 0 }; + var stretchYPosition = { x: 0, y: stretchCubeOffset, z: 0 }; stretchYPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, stretchYPosition)); - Overlays.editOverlay(handleStretchYSphere, { + Overlays.editOverlay(handleStretchYCube, { position: stretchYPosition, - dimensions: stretchSphereDimensions + rotation: rotationY, + dimensions: stretchCubeDimensions }); - var stretchZPosition = { x: 0, y: 0, z: stretchSphereOffset }; + var stretchZPosition = { x: 0, y: 0, z: stretchCubeOffset }; stretchZPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, stretchZPosition)); - Overlays.editOverlay(handleStretchZSphere, { - position: stretchZPosition, - dimensions: stretchSphereDimensions + Overlays.editOverlay(handleStretchZCube, { + position: stretchZPosition, + rotation: rotationZ, + dimensions: stretchCubeDimensions }); // UPDATE STRETCH HIGHLIGHT PANELS - var scaleRBFCubePositionRotated = Vec3.multiplyQbyV(rotationInverse, scaleRBFCubePosition); - var scaleRTFCubePositionRotated = Vec3.multiplyQbyV(rotationInverse, scaleRTFCubePosition); - var scaleLTNCubePositionRotated = Vec3.multiplyQbyV(rotationInverse, scaleLTNCubePosition); - var scaleRTNCubePositionRotated = Vec3.multiplyQbyV(rotationInverse, scaleRTNCubePosition); - var stretchPanelXDimensions = Vec3.subtract(scaleRTNCubePositionRotated, scaleRBFCubePositionRotated); + var RBFPositionRotated = Vec3.multiplyQbyV(rotationInverse, RBFPosition); + var RTFPositionRotated = Vec3.multiplyQbyV(rotationInverse, RTFPosition); + var LTNPositionRotated = Vec3.multiplyQbyV(rotationInverse, LTNPosition); + var RTNPositionRotated = Vec3.multiplyQbyV(rotationInverse, RTNPosition); + var stretchPanelXDimensions = Vec3.subtract(RTNPositionRotated, RBFPositionRotated); var tempY = Math.abs(stretchPanelXDimensions.y); stretchPanelXDimensions.x = STRETCH_PANEL_WIDTH; stretchPanelXDimensions.y = Math.abs(stretchPanelXDimensions.z); @@ -1555,7 +1479,7 @@ SelectionDisplay = (function() { rotation: rotationZ, dimensions: stretchPanelXDimensions }); - var stretchPanelYDimensions = Vec3.subtract(scaleLTNCubePositionRotated, scaleRTFCubePositionRotated); + var stretchPanelYDimensions = Vec3.subtract(LTNPositionRotated, RTFPositionRotated); var tempX = Math.abs(stretchPanelYDimensions.x); stretchPanelYDimensions.x = Math.abs(stretchPanelYDimensions.z); stretchPanelYDimensions.y = STRETCH_PANEL_WIDTH; @@ -1566,7 +1490,7 @@ SelectionDisplay = (function() { rotation: rotationY, dimensions: stretchPanelYDimensions }); - var stretchPanelZDimensions = Vec3.subtract(scaleLTNCubePositionRotated, scaleRBFCubePositionRotated); + var stretchPanelZDimensions = Vec3.subtract(LTNPositionRotated, RBFPositionRotated); tempX = Math.abs(stretchPanelZDimensions.x); stretchPanelZDimensions.x = Math.abs(stretchPanelZDimensions.y); stretchPanelZDimensions.y = tempX; @@ -1622,15 +1546,10 @@ SelectionDisplay = (function() { that.setHandleRotateRollVisible(!activeTool || isActiveTool(handleRotateRollRing)); var showScaleStretch = !activeTool && SelectionManager.selections.length === 1 && spaceMode === SPACE_LOCAL; - that.setHandleStretchXVisible(showScaleStretch || isActiveTool(handleStretchXSphere)); - that.setHandleStretchYVisible(showScaleStretch || isActiveTool(handleStretchYSphere)); - that.setHandleStretchZVisible(showScaleStretch || isActiveTool(handleStretchZSphere)); - that.setHandleScaleCubeVisible(showScaleStretch || isActiveTool(handleScaleLBNCube) || - isActiveTool(handleScaleRBNCube) || isActiveTool(handleScaleLBFCube) || - isActiveTool(handleScaleRBFCube) || isActiveTool(handleScaleLTNCube) || - isActiveTool(handleScaleRTNCube) || isActiveTool(handleScaleLTFCube) || - isActiveTool(handleScaleRTFCube) || isActiveTool(handleStretchXSphere) || - isActiveTool(handleStretchYSphere) || isActiveTool(handleStretchZSphere)); + that.setHandleStretchXVisible(showScaleStretch || isActiveTool(handleStretchXCube)); + that.setHandleStretchYVisible(showScaleStretch || isActiveTool(handleStretchYCube)); + that.setHandleStretchZVisible(showScaleStretch || isActiveTool(handleStretchZCube)); + that.setHandleScaleCubeVisible(showScaleStretch || isActiveTool(handleScaleCube)); var showOutlineForZone = (SelectionManager.selections.length === 1 && typeof SelectionManager.savedProperties[SelectionManager.selections[0]] !== "undefined" && @@ -1721,15 +1640,15 @@ SelectionDisplay = (function() { }; that.setHandleStretchXVisible = function(isVisible) { - Overlays.editOverlay(handleStretchXSphere, { visible: isVisible }); + Overlays.editOverlay(handleStretchXCube, { visible: isVisible }); }; that.setHandleStretchYVisible = function(isVisible) { - Overlays.editOverlay(handleStretchYSphere, { visible: isVisible }); + Overlays.editOverlay(handleStretchYCube, { visible: isVisible }); }; that.setHandleStretchZVisible = function(isVisible) { - Overlays.editOverlay(handleStretchZSphere, { visible: isVisible }); + Overlays.editOverlay(handleStretchZCube, { visible: isVisible }); }; // FUNCTION: SET HANDLE SCALE VISIBLE @@ -1739,14 +1658,7 @@ SelectionDisplay = (function() { }; that.setHandleScaleCubeVisible = function(isVisible) { - Overlays.editOverlay(handleScaleLBNCube, { visible: isVisible }); - Overlays.editOverlay(handleScaleRBNCube, { visible: isVisible }); - Overlays.editOverlay(handleScaleLBFCube, { visible: isVisible }); - Overlays.editOverlay(handleScaleRBFCube, { visible: isVisible }); - Overlays.editOverlay(handleScaleLTNCube, { visible: isVisible }); - Overlays.editOverlay(handleScaleRTNCube, { visible: isVisible }); - Overlays.editOverlay(handleScaleLTFCube, { visible: isVisible }); - Overlays.editOverlay(handleScaleRTFCube, { visible: isVisible }); + Overlays.editOverlay(handleScaleCube, { visible: isVisible }); }; that.setHandleScaleEdgeVisible = function(isVisible) { @@ -2157,6 +2069,8 @@ SelectionDisplay = (function() { var previousPickRay = null; var onBegin = function(event, pickRay, pickResult) { + var proportional = directionEnum === STRETCH_DIRECTION.ALL; + var properties = Entities.getEntityProperties(SelectionManager.selections[0]); initialProperties = properties; rotation = (spaceMode === SPACE_LOCAL) ? properties.rotation : Quat.IDENTITY; @@ -2244,9 +2158,17 @@ SelectionDisplay = (function() { } planeNormal = Vec3.multiplyQbyV(rotation, planeNormal); - lastPick = rayPlaneIntersection(pickRay, - pickRayPosition, - planeNormal); + + if (proportional) { + lastPick = pickRay.origin; + } else { + lastPick = rayPlaneIntersection(pickRay, + pickRayPosition, + planeNormal); + } + + Vec3.print("DBACK TEST begin pickRayPosition ", pickRayPosition); + Vec3.print("DBACK TEST begin lastPick ", lastPick); var planeNormal3D = { x: 0, @@ -2351,7 +2273,23 @@ SelectionDisplay = (function() { vector = grid.snapToSpacing(vector); var changeInDimensions = Vec3.multiply(NEGATE_VECTOR, vec3Mult(localSigns, vector)); - if (directionEnum === STRETCH_DIRECTION.ALL) { + + if (proportional) { + newPick = pickRay.origin; + var pickDifference = Vec3.subtract(newPick, lastPick); + Vec3.print("DBACK TEST move newPick ", newPick); + Vec3.print("DBACK TEST move pickDifference ", pickDifference); + changeInDimensions = + } + + //Vec3.print("DBACK TEST move pickRay.origin ", pickRay.origin); + //Vec3.print("DBACK TEST move pickRay.direction ", pickRay.direction); + //Vec3.print("DBACK TEST move newPick ", newPick); + //Vec3.print("DBACK TEST move vector ", vector); + //Vec3.print("DBACK TEST move changeInDimensions ", changeInDimensions); + + + if (proportional) { var toCameraDistance = getDistanceToCamera(position); var dimensionsMultiple = toCameraDistance * STRETCH_DIRECTION_ALL_CAMERA_DISTANCE_MULTIPLE; changeInDimensions = Vec3.multiply(changeInDimensions, dimensionsMultiple); @@ -2393,9 +2331,9 @@ SelectionDisplay = (function() { newDimensions.z = minimumDimension; changeInDimensions.z = minimumDimension - initialDimensions.z; } - + var changeInPosition = Vec3.multiplyQbyV(rotation, vec3Mult(localDeltaPivot, changeInDimensions)); - if (directionEnum === STRETCH_DIRECTION.ALL) { + if (proportional) { changeInPosition = { x: 0, y: 0, z: 0 }; } var newPosition = Vec3.sum(initialPosition, changeInPosition); @@ -2446,35 +2384,10 @@ SelectionDisplay = (function() { } // TOOL DEFINITION: HANDLE SCALE TOOL - function addHandleScaleTool(overlay, mode, directionEnum) { - var directionVector, offset, selectedHandle; - if (directionEnum === SCALE_DIRECTION.LBN) { - directionVector = { x: 1, y: 1, z: 1 }; - selectedHandle = handleScaleLBNCube; - } else if (directionEnum === SCALE_DIRECTION.RBN) { - directionVector = { x: -1, y: 1, z: 1 }; - selectedHandle = handleScaleRBNCube; - } else if (directionEnum === SCALE_DIRECTION.LBF) { - directionVector = { x: 1, y: 1, z: -1 }; - selectedHandle = handleScaleLBFCube; - } else if (directionEnum === SCALE_DIRECTION.RBF) { - directionVector = { x: -1, y: 1, z: -1 }; - selectedHandle = handleScaleRBFCube; - } else if (directionEnum === SCALE_DIRECTION.LTN) { - directionVector = { x: 1, y: -1, z: 1 }; - selectedHandle = handleScaleLTNCube; - } else if (directionEnum === SCALE_DIRECTION.RTN) { - directionVector = { x: -1, y: -1, z: 1 }; - selectedHandle = handleScaleRTNCube; - } else if (directionEnum === SCALE_DIRECTION.LTF) { - directionVector = { x: 1, y: -1, z: -1 }; - selectedHandle = handleScaleLTFCube; - } else if (directionEnum === SCALE_DIRECTION.RTF) { - directionVector = { x: -1, y: -1, z: -1 }; - selectedHandle = handleScaleRTFCube; - } - offset = Vec3.multiply(directionVector, NEGATE_VECTOR); - var tool = makeStretchTool(mode, STRETCH_DIRECTION.ALL, directionVector, directionVector, offset, null, selectedHandle); + function addHandleScaleTool(overlay, mode) { + var directionVector = { x:0, y:0, z:0 }; + var offset = { x:0, y:0, z:0 }; + var tool = makeStretchTool(mode, STRETCH_DIRECTION.ALL, directionVector, directionVector, offset, null, handleScaleCube); return addHandleTool(overlay, tool); } @@ -2747,18 +2660,11 @@ SelectionDisplay = (function() { addHandleRotateTool(handleRotateYawRing, "ROTATE_YAW", ROTATE_DIRECTION.YAW); addHandleRotateTool(handleRotateRollRing, "ROTATE_ROLL", ROTATE_DIRECTION.ROLL); - addHandleStretchTool(handleStretchXSphere, "STRETCH_X", STRETCH_DIRECTION.X); - addHandleStretchTool(handleStretchYSphere, "STRETCH_Y", STRETCH_DIRECTION.Y); - addHandleStretchTool(handleStretchZSphere, "STRETCH_Z", STRETCH_DIRECTION.Z); - - addHandleScaleTool(handleScaleLBNCube, "SCALE_LBN", SCALE_DIRECTION.LBN); - addHandleScaleTool(handleScaleRBNCube, "SCALE_RBN", SCALE_DIRECTION.RBN); - addHandleScaleTool(handleScaleLBFCube, "SCALE_LBF", SCALE_DIRECTION.LBF); - addHandleScaleTool(handleScaleRBFCube, "SCALE_RBF", SCALE_DIRECTION.RBF); - addHandleScaleTool(handleScaleLTNCube, "SCALE_LTN", SCALE_DIRECTION.LTN); - addHandleScaleTool(handleScaleRTNCube, "SCALE_RTN", SCALE_DIRECTION.RTN); - addHandleScaleTool(handleScaleLTFCube, "SCALE_LTF", SCALE_DIRECTION.LTF); - addHandleScaleTool(handleScaleRTFCube, "SCALE_RTF", SCALE_DIRECTION.RTF); + addHandleStretchTool(handleStretchXCube, "STRETCH_X", STRETCH_DIRECTION.X); + addHandleStretchTool(handleStretchYCube, "STRETCH_Y", STRETCH_DIRECTION.Y); + addHandleStretchTool(handleStretchZCube, "STRETCH_Z", STRETCH_DIRECTION.Z); + addHandleScaleTool(handleScaleCube, "SCALE"); + return that; }()); From 8eddb36c825acb3f6e5fffdc861bb6dc89bb7f31 Mon Sep 17 00:00:00 2001 From: David Back Date: Wed, 22 Aug 2018 17:29:40 -0700 Subject: [PATCH 076/545] resize scale cube --- .../system/libraries/entitySelectionTool.js | 70 +++++++------------ 1 file changed, 25 insertions(+), 45 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index bc36024e07..f251a1611c 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -441,7 +441,7 @@ SelectionDisplay = (function() { var STRETCH_PANEL_WIDTH = 0.01; var SCALE_EDGE_OFFSET = 0.5; - var SCALE_CUBE_CAMERA_DISTANCE_MULTIPLE = 0.0125; + var SCALE_CUBE_CAMERA_DISTANCE_MULTIPLE = 0.02; var CLONER_OFFSET = { x: 0.9, y: -0.9, z: 0.9 }; @@ -617,7 +617,7 @@ SelectionDisplay = (function() { var handleStretchZPanel = Overlays.addOverlay("shape", handlePropertiesStretchPanel); Overlays.editOverlay(handleStretchZPanel, { color: COLOR_BLUE }); - var handleScaleCube = Overlays.addOverlay("cube", { + var handleScaleCube = Overlays.addOverlay("cube", { size: 0.025, color: COLOR_SCALE_CUBE, solid: true, @@ -1393,8 +1393,8 @@ SelectionDisplay = (function() { }); // UPDATE SCALE CUBE - var scaleCubeRotation = spaceMode === SPACE_LOCAL ? rotation : Quat.IDENTITY; - var scaleCubeDimension = rotateDimension * SCALE_CUBE_CAMERA_DISTANCE_MULTIPLE / + var scaleCubeRotation = spaceMode === SPACE_LOCAL ? rotation : Quat.IDENTITY; + var scaleCubeDimension = rotateDimension * SCALE_CUBE_CAMERA_DISTANCE_MULTIPLE / ROTATE_RING_CAMERA_DISTANCE_MULTIPLE; var scaleCubeDimensions = { x: scaleCubeDimension, y: scaleCubeDimension, z: scaleCubeDimension }; Overlays.editOverlay(handleScaleCube, { @@ -1404,10 +1404,10 @@ SelectionDisplay = (function() { }); // UPDATE SCALE EDGES - var edgeOffsetX = SCALE_EDGE_OFFSET * dimensions.x; - var edgeOffsetY = SCALE_EDGE_OFFSET * dimensions.y; - var edgeOffsetZ = SCALE_EDGE_OFFSET * dimensions.z; - var LBNPosition = { x: -edgeOffsetX, y: -edgeOffsetY, z: -edgeOffsetZ }; + var edgeOffsetX = SCALE_EDGE_OFFSET * dimensions.x; + var edgeOffsetY = SCALE_EDGE_OFFSET * dimensions.y; + var edgeOffsetZ = SCALE_EDGE_OFFSET * dimensions.z; + var LBNPosition = { x: -edgeOffsetX, y: -edgeOffsetY, z: -edgeOffsetZ }; LBNPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, LBNPosition)); var RBNPosition = { x: edgeOffsetX, y: -edgeOffsetY, z: -edgeOffsetZ }; RBNPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, RBNPosition)); @@ -1445,21 +1445,21 @@ SelectionDisplay = (function() { stretchXPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, stretchXPosition)); Overlays.editOverlay(handleStretchXCube, { position: stretchXPosition, - rotation: rotationX, + rotation: rotationX, dimensions: stretchCubeDimensions }); var stretchYPosition = { x: 0, y: stretchCubeOffset, z: 0 }; stretchYPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, stretchYPosition)); Overlays.editOverlay(handleStretchYCube, { position: stretchYPosition, - rotation: rotationY, + rotation: rotationY, dimensions: stretchCubeDimensions }); var stretchZPosition = { x: 0, y: 0, z: stretchCubeOffset }; stretchZPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, stretchZPosition)); Overlays.editOverlay(handleStretchZCube, { position: stretchZPosition, - rotation: rotationZ, + rotation: rotationZ, dimensions: stretchCubeDimensions }); @@ -2067,10 +2067,9 @@ SelectionDisplay = (function() { var pickRayPosition3D = null; var rotation = null; var previousPickRay = null; + var beginMouseEvent = null; - var onBegin = function(event, pickRay, pickResult) { - var proportional = directionEnum === STRETCH_DIRECTION.ALL; - + var onBegin = function(event, pickRay, pickResult) { var properties = Entities.getEntityProperties(SelectionManager.selections[0]); initialProperties = properties; rotation = (spaceMode === SPACE_LOCAL) ? properties.rotation : Quat.IDENTITY; @@ -2158,17 +2157,7 @@ SelectionDisplay = (function() { } planeNormal = Vec3.multiplyQbyV(rotation, planeNormal); - - if (proportional) { - lastPick = pickRay.origin; - } else { - lastPick = rayPlaneIntersection(pickRay, - pickRayPosition, - planeNormal); - } - - Vec3.print("DBACK TEST begin pickRayPosition ", pickRayPosition); - Vec3.print("DBACK TEST begin lastPick ", lastPick); + lastPick = rayPlaneIntersection(pickRay, pickRayPosition, planeNormal); var planeNormal3D = { x: 0, @@ -2208,6 +2197,7 @@ SelectionDisplay = (function() { } previousPickRay = pickRay; + beginMouseEvent = event; }; var onEnd = function(event, reason) { @@ -2273,23 +2263,13 @@ SelectionDisplay = (function() { vector = grid.snapToSpacing(vector); var changeInDimensions = Vec3.multiply(NEGATE_VECTOR, vec3Mult(localSigns, vector)); - - if (proportional) { - newPick = pickRay.origin; - var pickDifference = Vec3.subtract(newPick, lastPick); - Vec3.print("DBACK TEST move newPick ", newPick); - Vec3.print("DBACK TEST move pickDifference ", pickDifference); - changeInDimensions = - } - - //Vec3.print("DBACK TEST move pickRay.origin ", pickRay.origin); - //Vec3.print("DBACK TEST move pickRay.direction ", pickRay.direction); - //Vec3.print("DBACK TEST move newPick ", newPick); - //Vec3.print("DBACK TEST move vector ", vector); - //Vec3.print("DBACK TEST move changeInDimensions ", changeInDimensions); - - - if (proportional) { + + if (proportional) { + var viewportDimensions = Controller.getViewportDimensions(); + var mouseXDifference = (event.x - beginMouseEvent.x) / viewportDimensions.x; + var mouseYDifference = (beginMouseEvent.y - event.y) / viewportDimensions.y; + var mouseDifference = mouseXDifference + mouseYDifference; + changeInDimensions = { x:mouseDifference, y:mouseDifference, z:mouseDifference }; var toCameraDistance = getDistanceToCamera(position); var dimensionsMultiple = toCameraDistance * STRETCH_DIRECTION_ALL_CAMERA_DISTANCE_MULTIPLE; changeInDimensions = Vec3.multiply(changeInDimensions, dimensionsMultiple); @@ -2385,8 +2365,8 @@ SelectionDisplay = (function() { // TOOL DEFINITION: HANDLE SCALE TOOL function addHandleScaleTool(overlay, mode) { - var directionVector = { x:0, y:0, z:0 }; - var offset = { x:0, y:0, z:0 }; + var directionVector = { x:0, y:0, z:0 }; + var offset = { x:0, y:0, z:0 }; var tool = makeStretchTool(mode, STRETCH_DIRECTION.ALL, directionVector, directionVector, offset, null, handleScaleCube); return addHandleTool(overlay, tool); } @@ -2665,6 +2645,6 @@ SelectionDisplay = (function() { addHandleStretchTool(handleStretchZCube, "STRETCH_Z", STRETCH_DIRECTION.Z); addHandleScaleTool(handleScaleCube, "SCALE"); - + return that; }()); From 874d9251e76996f1371c4d755db598bb66972906 Mon Sep 17 00:00:00 2001 From: amantley Date: Wed, 22 Aug 2018 17:32:46 -0700 Subject: [PATCH 077/545] demo version, next to implement in c++ --- scripts/developer/rotateApp.js | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/scripts/developer/rotateApp.js b/scripts/developer/rotateApp.js index 4d18910335..60d78d66d9 100644 --- a/scripts/developer/rotateApp.js +++ b/scripts/developer/rotateApp.js @@ -260,6 +260,15 @@ function limitAngle(angle) { } function computeHandAzimuths(timeElapsed) { + + // var leftHandPositionRigSpace = Vec3.multiplyQbyV(Quat.inverse(CHANGE_OF_BASIS_ROTATION), currentStateReadings.lhandPose.translation); + // var rightHandPositionRigSpace = Vec3.multiplyQbyV(Quat.inverse(CHANGE_OF_BASIS_ROTATION), currentStateReadings.rhandPose.translation); + + + // var hipToLeftHand = Quat.lookAtSimple({ x: 0, y: 0, z: 0 }, { x: leftHandPositionRigSpace.x, y: 0, z: leftHandPositionRigSpace.z }); + // var hipToRightHand = Quat.lookAtSimple({ x: 0, y: 0, z: 0 }, { x: rightHandPositionRigSpace.x, y: 0, z: rightHandPositionRigSpace.z }); + // var hipToHandHalfway = Quat.slerp(hipToLeftHand, hipToRightHand, 0.5); + var leftHand = currentStateReadings.lhandPose.translation; var rightHand = currentStateReadings.rhandPose.translation; var head = currentStateReadings.headPose.translation; @@ -299,17 +308,21 @@ function computeHandAzimuths(timeElapsed) { // get it into radians too!! // average head and hands 50/50 - print("hands azimuth " + leftRightMidpointAverage + " head azimuth " + headPoseAverageEulers.y) + // print("hands azimuth " + leftRightMidpointAverage + " head azimuth " + headPoseAverageEulers.y); var headPlusHands = (leftRightMidpointAverage + headPoseAverageEulers.y) / 2.0; if ((Math.abs(headPlusHands / 180.0) * Math.PI) > angleThresholdProperty.value) { - print("recenter the feet under the head"); + //print("recenter the feet under the head"); MyAvatar.triggerRotationRecenter(); hipToLHandAverage = { x: 0, y: 0, z: 0, w: 1 }; hipToRHandAverage = { x: 0, y: 0, z: 0, w: 1 }; headPoseAverageOrientation = { x: 0, y: 0, z: 0, w: 1 }; } - return Quat.fromVec3Degrees({ x: 0, y: leftRightMidpoint, z: 0 }); + // put a hard max on this easing function. + var rotateAngle = ((Math.cos((leftRightMidpoint / 180.0) * Math.PI) + 2.0)/3.0) * leftRightMidpoint; + print("rotate angle " + rotateAngle); + + return Quat.fromVec3Degrees({ x: 0, y: rotateAngle, z: 0 }); } From c474f38860afef8694d4736016c549dbd6bb3d9e Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 22 Aug 2018 17:49:02 -0700 Subject: [PATCH 078/545] force coarse picking, sort avatars --- interface/src/Menu.cpp | 6 + interface/src/Menu.h | 1 + interface/src/avatar/AvatarManager.cpp | 174 +++++++++++++++---------- interface/src/avatar/AvatarManager.h | 2 + interface/src/raypick/ParabolaPick.cpp | 7 +- interface/src/raypick/RayPick.cpp | 7 +- libraries/avatars/src/AvatarData.h | 2 +- libraries/pointers/src/Pick.cpp | 4 + libraries/pointers/src/PickManager.h | 11 +- libraries/shared/src/TriangleSet.cpp | 54 ++++---- libraries/shared/src/TriangleSet.h | 18 +-- 11 files changed, 178 insertions(+), 108 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index fe7083ea30..d4c74127c8 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -46,6 +46,7 @@ #include "InterfaceLogging.h" #include "LocationBookmarks.h" #include "DeferredLightingEffect.h" +#include "PickManager.h" #include "AmbientOcclusionEffect.h" #include "RenderShadowTask.h" @@ -688,6 +689,11 @@ Menu::Menu() { addCheckableActionToQMenuAndActionHash(physicsOptionsMenu, MenuOption::PhysicsShowBulletConstraints, 0, false, qApp, SLOT(setShowBulletConstraints(bool))); addCheckableActionToQMenuAndActionHash(physicsOptionsMenu, MenuOption::PhysicsShowBulletConstraintLimits, 0, false, qApp, SLOT(setShowBulletConstraintLimits(bool))); + // Developer > Picking >>> + MenuWrapper* pickingOptionsMenu = developerMenu->addMenu("Picking"); + addCheckableActionToQMenuAndActionHash(pickingOptionsMenu, MenuOption::ForceCoarsePicking, 0, false, + DependencyManager::get().data(), SLOT(setForceCoarsePicking(bool))); + // Developer > Display Crash Options addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::DisplayCrashOptions, 0, true); // Developer > Crash >>> diff --git a/interface/src/Menu.h b/interface/src/Menu.h index c489a3f0b0..4386bec5ae 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -221,6 +221,7 @@ namespace MenuOption { const QString NotificationSounds = "play_notification_sounds"; const QString NotificationSoundsSnapshot = "play_notification_sounds_snapshot"; const QString NotificationSoundsTablet = "play_notification_sounds_tablet"; + const QString ForceCoarsePicking = "Force Coarse Picking"; } #endif // hifi_Menu_h diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 139f44d58b..6fb35ec1da 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -553,6 +553,14 @@ RayToAvatarIntersectionResult AvatarManager::findRayIntersectionVector(const Pic return result; } + // It's better to intersect the ray against the avatar's actual mesh, but this is currently difficult to + // do, because the transformed mesh data only exists over in GPU-land. As a compromise, this code + // intersects against the avatars capsule and then against the (T-pose) mesh. The end effect is that picking + // against the avatar is sort-of right, but you likely wont be able to pick against the arms. + + // TODO -- find a way to extract transformed avatar mesh data from the rendering engine. + + std::vector sortedAvatars; auto avatarHashCopy = getHashCopy(); for (auto avatarData : avatarHashCopy) { auto avatar = std::static_pointer_cast(avatarData); @@ -561,47 +569,60 @@ RayToAvatarIntersectionResult AvatarManager::findRayIntersectionVector(const Pic continue; } - float distance; - BoxFace face; - glm::vec3 surfaceNormal; - - SkeletonModelPointer avatarModel = avatar->getSkeletonModel(); - - // It's better to intersect the ray against the avatar's actual mesh, but this is currently difficult to - // do, because the transformed mesh data only exists over in GPU-land. As a compromise, this code - // intersects against the avatars capsule and then against the (T-pose) mesh. The end effect is that picking - // against the avatar is sort-of right, but you likely wont be able to pick against the arms. - - // TODO -- find a way to extract transformed avatar mesh data from the rendering engine. - + float distance = FLT_MAX; +#if 0 // if we weren't picking against the capsule, we would want to pick against the avatarBounds... - // AABox avatarBounds = avatarModel->getRenderableMeshBound(); - // if (!avatarBounds.findRayIntersection(ray.origin, normDirection, distance, face, surfaceNormal)) { - // // ray doesn't intersect avatar's bounding-box - // continue; - // } - + SkeletonModelPointer avatarModel = avatar->getSkeletonModel(); + AABox avatarBounds = avatarModel->getRenderableMeshBound(); + if (avatarBounds.contains(ray.origin)) { + distance = 0.0f; + } else { + float boundDistance = FLT_MAX; + BoxFace face; + glm::vec3 surfaceNormal; + if (avatarBounds.findRayIntersection(ray.origin, ray.direction, boundDistance, face, surfaceNormal)) { + distance = boundDistance; + } + } +#else glm::vec3 start; glm::vec3 end; float radius; avatar->getCapsule(start, end, radius); - bool intersects = findRayCapsuleIntersection(ray.origin, ray.direction, start, end, radius, distance); - if (!intersects) { - // ray doesn't intersect avatar's capsule - continue; + findRayCapsuleIntersection(ray.origin, ray.direction, start, end, radius, distance); +#endif + + if (distance < FLT_MAX) { + sortedAvatars.emplace_back(distance, avatar); + } + } + + if (sortedAvatars.size() > 1) { + static auto comparator = [](const SortedAvatar& left, const SortedAvatar& right) { return left.first > right.first; }; + std::sort(sortedAvatars.begin(), sortedAvatars.end(), comparator); + } + + for (auto it = sortedAvatars.begin(); it != sortedAvatars.end(); ++it) { + const SortedAvatar& sortedAvatar = *it; + // We can exit once avatarCapsuleDistance > bestDistance + if (sortedAvatar.first > result.distance) { + break; } + float distance = FLT_MAX; + BoxFace face; + glm::vec3 surfaceNormal; QVariantMap extraInfo; - intersects = avatarModel->findRayIntersectionAgainstSubMeshes(ray.origin, ray.direction, - distance, face, surfaceNormal, extraInfo, true); - - if (intersects && (!result.intersects || distance < result.distance)) { - result.intersects = true; - result.avatarID = avatar->getID(); - result.distance = distance; - result.face = face; - result.surfaceNormal = surfaceNormal; - result.extraInfo = extraInfo; + SkeletonModelPointer avatarModel = sortedAvatar.second->getSkeletonModel(); + if (avatarModel->findRayIntersectionAgainstSubMeshes(ray.origin, ray.direction, distance, face, surfaceNormal, extraInfo, true)) { + if (distance < result.distance) { + result.intersects = true; + result.avatarID = sortedAvatar.second->getID(); + result.distance = distance; + result.face = face; + result.surfaceNormal = surfaceNormal; + result.extraInfo = extraInfo; + } } } @@ -625,6 +646,14 @@ ParabolaToAvatarIntersectionResult AvatarManager::findParabolaIntersectionVector return result; } + // It's better to intersect the ray against the avatar's actual mesh, but this is currently difficult to + // do, because the transformed mesh data only exists over in GPU-land. As a compromise, this code + // intersects against the avatars capsule and then against the (T-pose) mesh. The end effect is that picking + // against the avatar is sort-of right, but you likely wont be able to pick against the arms. + + // TODO -- find a way to extract transformed avatar mesh data from the rendering engine. + + std::vector sortedAvatars; auto avatarHashCopy = getHashCopy(); for (auto avatarData : avatarHashCopy) { auto avatar = std::static_pointer_cast(avatarData); @@ -633,47 +662,60 @@ ParabolaToAvatarIntersectionResult AvatarManager::findParabolaIntersectionVector continue; } - float parabolicDistance; - BoxFace face; - glm::vec3 surfaceNormal; - - SkeletonModelPointer avatarModel = avatar->getSkeletonModel(); - - // It's better to intersect the parabola against the avatar's actual mesh, but this is currently difficult to - // do, because the transformed mesh data only exists over in GPU-land. As a compromise, this code - // intersects against the avatars capsule and then against the (T-pose) mesh. The end effect is that picking - // against the avatar is sort-of right, but you likely wont be able to pick against the arms. - - // TODO -- find a way to extract transformed avatar mesh data from the rendering engine. - + float distance = FLT_MAX; +#if 0 // if we weren't picking against the capsule, we would want to pick against the avatarBounds... - // AABox avatarBounds = avatarModel->getRenderableMeshBound(); - // if (!avatarBounds.findParabolaIntersection(pick.origin, pick.velocity, pick.acceleration, parabolicDistance, face, surfaceNormal)) { - // // parabola doesn't intersect avatar's bounding-box - // continue; - // } - + SkeletonModelPointer avatarModel = avatar->getSkeletonModel(); + AABox avatarBounds = avatarModel->getRenderableMeshBound(); + if (avatarBounds.contains(pick.origin)) { + distance = 0.0f; + } else { + float boundDistance = FLT_MAX; + BoxFace face; + glm::vec3 surfaceNormal; + if (avatarBounds.findParabolaIntersection(pick.origin, pick.velocity, pick.acceleration, boundDistance, face, surfaceNormal)) { + distance = boundDistance; + } + } +#else glm::vec3 start; glm::vec3 end; float radius; avatar->getCapsule(start, end, radius); - bool intersects = findParabolaCapsuleIntersection(pick.origin, pick.velocity, pick.acceleration, start, end, radius, avatar->getWorldOrientation(), parabolicDistance); - if (!intersects) { - // ray doesn't intersect avatar's capsule - continue; + findParabolaCapsuleIntersection(pick.origin, pick.velocity, pick.acceleration, start, end, radius, avatar->getWorldOrientation(), distance); +#endif + + if (distance < FLT_MAX) { + sortedAvatars.emplace_back(distance, avatar); + } + } + + if (sortedAvatars.size() > 1) { + static auto comparator = [](const SortedAvatar& left, const SortedAvatar& right) { return left.first > right.first; }; + std::sort(sortedAvatars.begin(), sortedAvatars.end(), comparator); + } + + for (auto it = sortedAvatars.begin(); it != sortedAvatars.end(); ++it) { + const SortedAvatar& sortedAvatar = *it; + // We can exit once avatarCapsuleDistance > bestDistance + if (sortedAvatar.first > result.parabolicDistance) { + break; } + float parabolicDistance = FLT_MAX; + BoxFace face; + glm::vec3 surfaceNormal; QVariantMap extraInfo; - intersects = avatarModel->findParabolaIntersectionAgainstSubMeshes(pick.origin, pick.velocity, pick.acceleration, - parabolicDistance, face, surfaceNormal, extraInfo, true); - - if (intersects && (!result.intersects || parabolicDistance < result.parabolicDistance)) { - result.intersects = true; - result.avatarID = avatar->getID(); - result.parabolicDistance = parabolicDistance; - result.face = face; - result.surfaceNormal = surfaceNormal; - result.extraInfo = extraInfo; + SkeletonModelPointer avatarModel = sortedAvatar.second->getSkeletonModel(); + if (avatarModel->findParabolaIntersectionAgainstSubMeshes(pick.origin, pick.velocity, pick.acceleration, parabolicDistance, face, surfaceNormal, extraInfo, true)) { + if (parabolicDistance < result.parabolicDistance) { + result.intersects = true; + result.avatarID = sortedAvatar.second->getID(); + result.parabolicDistance = parabolicDistance; + result.face = face; + result.surfaceNormal = surfaceNormal; + result.extraInfo = extraInfo; + } } } diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index ecf9a2d735..a9c04e8473 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -27,6 +27,8 @@ #include "AvatarMotionState.h" #include "MyAvatar.h" +using SortedAvatar = std::pair>; + /**jsdoc * The AvatarManager API has properties and methods which manage Avatars within the same domain. * diff --git a/interface/src/raypick/ParabolaPick.cpp b/interface/src/raypick/ParabolaPick.cpp index b3e3f16345..f4db1df25a 100644 --- a/interface/src/raypick/ParabolaPick.cpp +++ b/interface/src/raypick/ParabolaPick.cpp @@ -13,11 +13,13 @@ #include "avatar/AvatarManager.h" #include "scripting/HMDScriptingInterface.h" #include "DependencyManager.h" +#include "PickManager.h" PickResultPointer ParabolaPick::getEntityIntersection(const PickParabola& pick) { if (glm::length2(pick.acceleration) > EPSILON && glm::length2(pick.velocity) > EPSILON) { + bool precisionPicking = !(getFilter().doesPickCoarse() || DependencyManager::get()->getForceCoarsePicking()); ParabolaToEntityIntersectionResult entityRes = - DependencyManager::get()->findParabolaIntersectionVector(pick, !getFilter().doesPickCoarse(), + DependencyManager::get()->findParabolaIntersectionVector(pick, precisionPicking, getIncludeItemsAs(), getIgnoreItemsAs(), !getFilter().doesPickInvisible(), !getFilter().doesPickNonCollidable()); if (entityRes.intersects) { return std::make_shared(IntersectionType::ENTITY, entityRes.entityID, entityRes.distance, entityRes.parabolicDistance, entityRes.intersection, pick, entityRes.surfaceNormal, entityRes.extraInfo); @@ -28,8 +30,9 @@ PickResultPointer ParabolaPick::getEntityIntersection(const PickParabola& pick) PickResultPointer ParabolaPick::getOverlayIntersection(const PickParabola& pick) { if (glm::length2(pick.acceleration) > EPSILON && glm::length2(pick.velocity) > EPSILON) { + bool precisionPicking = !(getFilter().doesPickCoarse() || DependencyManager::get()->getForceCoarsePicking()); ParabolaToOverlayIntersectionResult overlayRes = - qApp->getOverlays().findParabolaIntersectionVector(pick, !getFilter().doesPickCoarse(), + qApp->getOverlays().findParabolaIntersectionVector(pick, precisionPicking, getIncludeItemsAs(), getIgnoreItemsAs(), !getFilter().doesPickInvisible(), !getFilter().doesPickNonCollidable()); if (overlayRes.intersects) { return std::make_shared(IntersectionType::OVERLAY, overlayRes.overlayID, overlayRes.distance, overlayRes.parabolicDistance, overlayRes.intersection, pick, overlayRes.surfaceNormal, overlayRes.extraInfo); diff --git a/interface/src/raypick/RayPick.cpp b/interface/src/raypick/RayPick.cpp index 96b41dcc72..fde1da3f87 100644 --- a/interface/src/raypick/RayPick.cpp +++ b/interface/src/raypick/RayPick.cpp @@ -13,10 +13,12 @@ #include "avatar/AvatarManager.h" #include "scripting/HMDScriptingInterface.h" #include "DependencyManager.h" +#include "PickManager.h" PickResultPointer RayPick::getEntityIntersection(const PickRay& pick) { + bool precisionPicking = !(getFilter().doesPickCoarse() || DependencyManager::get()->getForceCoarsePicking()); RayToEntityIntersectionResult entityRes = - DependencyManager::get()->findRayIntersectionVector(pick, !getFilter().doesPickCoarse(), + DependencyManager::get()->findRayIntersectionVector(pick, precisionPicking, getIncludeItemsAs(), getIgnoreItemsAs(), !getFilter().doesPickInvisible(), !getFilter().doesPickNonCollidable()); if (entityRes.intersects) { return std::make_shared(IntersectionType::ENTITY, entityRes.entityID, entityRes.distance, entityRes.intersection, pick, entityRes.surfaceNormal, entityRes.extraInfo); @@ -26,8 +28,9 @@ PickResultPointer RayPick::getEntityIntersection(const PickRay& pick) { } PickResultPointer RayPick::getOverlayIntersection(const PickRay& pick) { + bool precisionPicking = !(getFilter().doesPickCoarse() || DependencyManager::get()->getForceCoarsePicking()); RayToOverlayIntersectionResult overlayRes = - qApp->getOverlays().findRayIntersectionVector(pick, !getFilter().doesPickCoarse(), + qApp->getOverlays().findRayIntersectionVector(pick, precisionPicking, getIncludeItemsAs(), getIgnoreItemsAs(), !getFilter().doesPickInvisible(), !getFilter().doesPickNonCollidable()); if (overlayRes.intersects) { return std::make_shared(IntersectionType::OVERLAY, overlayRes.overlayID, overlayRes.distance, overlayRes.intersection, pick, overlayRes.surfaceNormal, overlayRes.extraInfo); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 53a2a69119..9d4ba3902d 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -1559,7 +1559,7 @@ class RayToAvatarIntersectionResult { public: bool intersects { false }; QUuid avatarID; - float distance { 0.0f }; + float distance { FLT_MAX }; BoxFace face; glm::vec3 intersection; glm::vec3 surfaceNormal; diff --git a/libraries/pointers/src/Pick.cpp b/libraries/pointers/src/Pick.cpp index 4315409bdb..7ac53a2643 100644 --- a/libraries/pointers/src/Pick.cpp +++ b/libraries/pointers/src/Pick.cpp @@ -72,11 +72,15 @@ PickResultPointer PickQuery::getPrevPickResult() const { void PickQuery::setIgnoreItems(const QVector& ignoreItems) { withWriteLock([&] { _ignoreItems = ignoreItems; + // We sort these items here so the PickCacheOptimizer can catch cases where two picks have the same ignoreItems in a different order + std::sort(_ignoreItems.begin(), _ignoreItems.end(), std::less()); }); } void PickQuery::setIncludeItems(const QVector& includeItems) { withWriteLock([&] { _includeItems = includeItems; + // We sort these items here so the PickCacheOptimizer can catch cases where two picks have the same includeItems in a different order + std::sort(_includeItems.begin(), _includeItems.end(), std::less()); }); } \ No newline at end of file diff --git a/libraries/pointers/src/PickManager.h b/libraries/pointers/src/PickManager.h index 242550d837..595c43e71d 100644 --- a/libraries/pointers/src/PickManager.h +++ b/libraries/pointers/src/PickManager.h @@ -16,7 +16,10 @@ #include -class PickManager : public Dependency, protected ReadWriteLockable { +#include + +class PickManager : public QObject, public Dependency, protected ReadWriteLockable { + Q_OBJECT SINGLETON_DEPENDENCY public: @@ -53,7 +56,13 @@ public: unsigned int getPerFrameTimeBudget() const { return _perFrameTimeBudget; } void setPerFrameTimeBudget(unsigned int numUsecs) { _perFrameTimeBudget = numUsecs; } + bool getForceCoarsePicking() { return _forceCoarsePicking; } + +public slots: + void setForceCoarsePicking(bool forceCoarsePicking) { _forceCoarsePicking = forceCoarsePicking; } + protected: + bool _forceCoarsePicking { false }; std::function _shouldPickHUDOperator; std::function _calculatePos2DFromHUDOperator; diff --git a/libraries/shared/src/TriangleSet.cpp b/libraries/shared/src/TriangleSet.cpp index f3c0ef5776..1dc8c5657a 100644 --- a/libraries/shared/src/TriangleSet.cpp +++ b/libraries/shared/src/TriangleSet.cpp @@ -29,7 +29,7 @@ void TriangleSet::clear() { _bounds.clear(); _isBalanced = false; - _triangleOctree.clear(); + _triangleTree.clear(); } bool TriangleSet::convexHullContains(const glm::vec3& point) const { @@ -53,16 +53,16 @@ void TriangleSet::debugDump() { qDebug() << __FUNCTION__; qDebug() << "bounds:" << getBounds(); qDebug() << "triangles:" << size() << "at top level...."; - qDebug() << "----- _triangleOctree -----"; - _triangleOctree.debugDump(); + qDebug() << "----- _triangleTree -----"; + _triangleTree.debugDump(); } -void TriangleSet::balanceOctree() { - _triangleOctree.reset(_bounds); +void TriangleSet::balanceTree() { + _triangleTree.reset(_bounds); // insert all the triangles for (size_t i = 0; i < _triangles.size(); i++) { - _triangleOctree.insert(i); + _triangleTree.insert(i); } _isBalanced = true; @@ -77,13 +77,13 @@ void TriangleSet::balanceOctree() { // With a k-d tree: 2 ^ MAX_DEPTH = 4096 leaves static const int MAX_DEPTH = 12; -TriangleSet::TriangleOctreeCell::TriangleOctreeCell(std::vector& allTriangles, const AABox& bounds, int depth) : +TriangleSet::TriangleTreeCell::TriangleTreeCell(std::vector& allTriangles, const AABox& bounds, int depth) : _allTriangles(allTriangles) { reset(bounds, depth); } -void TriangleSet::TriangleOctreeCell::clear() { +void TriangleSet::TriangleTreeCell::clear() { _population = 0; _triangleIndices.clear(); _bounds.clear(); @@ -91,13 +91,13 @@ void TriangleSet::TriangleOctreeCell::clear() { _children.second.reset(); } -void TriangleSet::TriangleOctreeCell::reset(const AABox& bounds, int depth) { +void TriangleSet::TriangleTreeCell::reset(const AABox& bounds, int depth) { clear(); _bounds = bounds; _depth = depth; } -void TriangleSet::TriangleOctreeCell::debugDump() { +void TriangleSet::TriangleTreeCell::debugDump() { qDebug() << __FUNCTION__; qDebug() << " bounds:" << getBounds(); qDebug() << " depth:" << _depth; @@ -123,7 +123,7 @@ void TriangleSet::TriangleOctreeCell::debugDump() { } } -std::pair TriangleSet::TriangleOctreeCell::getTriangleOctreeCellChildBounds() { +std::pair TriangleSet::TriangleTreeCell::getTriangleTreeCellChildBounds() { std::pair toReturn; int axis = 0; // find biggest axis @@ -145,20 +145,20 @@ std::pair TriangleSet::TriangleOctreeCell::getTriangleOctreeCellCh return toReturn; } -void TriangleSet::TriangleOctreeCell::insert(size_t triangleIndex) { +void TriangleSet::TriangleTreeCell::insert(size_t triangleIndex) { _population++; // if we're not yet at the max depth, then check which child the triangle fits in if (_depth < MAX_DEPTH) { const Triangle& triangle = _allTriangles[triangleIndex]; - auto childBounds = getTriangleOctreeCellChildBounds(); + auto childBounds = getTriangleTreeCellChildBounds(); - auto insertOperator = [&](const AABox& childBound, std::shared_ptr& child) { + auto insertOperator = [&](const AABox& childBound, std::shared_ptr& child) { // if the child AABox would contain the triangle... if (childBound.contains(triangle)) { // if the child cell doesn't yet exist, create it... if (!child) { - child = std::make_shared(_allTriangles, childBound, _depth + 1); + child = std::make_shared(_allTriangles, childBound, _depth + 1); } // insert the triangleIndex in the child cell @@ -179,19 +179,19 @@ void TriangleSet::TriangleOctreeCell::insert(size_t triangleIndex) { bool TriangleSet::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face, Triangle& triangle, bool precision, bool allowBackface) { if (!_isBalanced) { - balanceOctree(); + balanceTree(); } float localDistance = distance; int trianglesTouched = 0; - bool hit = _triangleOctree.findRayIntersection(origin, direction, localDistance, face, triangle, precision, trianglesTouched, allowBackface); + bool hit = _triangleTree.findRayIntersection(origin, direction, localDistance, face, triangle, precision, trianglesTouched, allowBackface); if (hit) { distance = localDistance; } #if WANT_DEBUGGING if (precision) { - qDebug() << "trianglesTouched :" << trianglesTouched << "out of:" << _triangleOctree._population << "_triangles.size:" << _triangles.size(); + qDebug() << "trianglesTouched :" << trianglesTouched << "out of:" << _triangleTree._population << "_triangles.size:" << _triangles.size(); } #endif return hit; @@ -199,7 +199,7 @@ bool TriangleSet::findRayIntersection(const glm::vec3& origin, const glm::vec3& // Determine of the given ray (origin/direction) in model space intersects with any triangles // in the set. If an intersection occurs, the distance and surface normal will be provided. -bool TriangleSet::TriangleOctreeCell::findRayIntersectionInternal(const glm::vec3& origin, const glm::vec3& direction, +bool TriangleSet::TriangleTreeCell::findRayIntersectionInternal(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face, Triangle& triangle, bool precision, int& trianglesTouched, bool allowBackface) { bool intersectedSomething = false; @@ -232,7 +232,7 @@ bool TriangleSet::TriangleOctreeCell::findRayIntersectionInternal(const glm::vec return intersectedSomething; } -bool TriangleSet::TriangleOctreeCell::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, +bool TriangleSet::TriangleTreeCell::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face, Triangle& triangle, bool precision, int& trianglesTouched, bool allowBackface) { if (_population < 1) { @@ -261,7 +261,7 @@ bool TriangleSet::TriangleOctreeCell::findRayIntersection(const glm::vec3& origi // if we're not yet at the max depth, then check our children if (_depth < MAX_DEPTH) { std::list sortedTriangleCells; - auto sortingOperator = [&](std::shared_ptr& child) { + auto sortingOperator = [&](std::shared_ptr& child) { if (child) { float priority = FLT_MAX; if (child->getBounds().contains(origin)) { @@ -328,25 +328,25 @@ bool TriangleSet::TriangleOctreeCell::findRayIntersection(const glm::vec3& origi bool TriangleSet::findParabolaIntersection(const glm::vec3& origin, const glm::vec3& velocity, const glm::vec3& acceleration, float& parabolicDistance, BoxFace& face, Triangle& triangle, bool precision, bool allowBackface) { if (!_isBalanced) { - balanceOctree(); + balanceTree(); } float localDistance = parabolicDistance; int trianglesTouched = 0; - bool hit = _triangleOctree.findParabolaIntersection(origin, velocity, acceleration, localDistance, face, triangle, precision, trianglesTouched, allowBackface); + bool hit = _triangleTree.findParabolaIntersection(origin, velocity, acceleration, localDistance, face, triangle, precision, trianglesTouched, allowBackface); if (hit) { parabolicDistance = localDistance; } #if WANT_DEBUGGING if (precision) { - qDebug() << "trianglesTouched :" << trianglesTouched << "out of:" << _triangleOctree._population << "_triangles.size:" << _triangles.size(); + qDebug() << "trianglesTouched :" << trianglesTouched << "out of:" << _triangleTree._population << "_triangles.size:" << _triangles.size(); } #endif return hit; } -bool TriangleSet::TriangleOctreeCell::findParabolaIntersectionInternal(const glm::vec3& origin, const glm::vec3& velocity, +bool TriangleSet::TriangleTreeCell::findParabolaIntersectionInternal(const glm::vec3& origin, const glm::vec3& velocity, const glm::vec3& acceleration, float& parabolicDistance, BoxFace& face, Triangle& triangle, bool precision, int& trianglesTouched, bool allowBackface) { @@ -380,7 +380,7 @@ bool TriangleSet::TriangleOctreeCell::findParabolaIntersectionInternal(const glm return intersectedSomething; } -bool TriangleSet::TriangleOctreeCell::findParabolaIntersection(const glm::vec3& origin, const glm::vec3& velocity, +bool TriangleSet::TriangleTreeCell::findParabolaIntersection(const glm::vec3& origin, const glm::vec3& velocity, const glm::vec3& acceleration, float& parabolicDistance, BoxFace& face, Triangle& triangle, bool precision, int& trianglesTouched, bool allowBackface) { @@ -410,7 +410,7 @@ bool TriangleSet::TriangleOctreeCell::findParabolaIntersection(const glm::vec3& // if we're not yet at the max depth, then check our children if (_depth < MAX_DEPTH) { std::list sortedTriangleCells; - auto sortingOperator = [&](std::shared_ptr& child) { + auto sortingOperator = [&](std::shared_ptr& child) { if (child) { float priority = FLT_MAX; if (child->getBounds().contains(origin)) { diff --git a/libraries/shared/src/TriangleSet.h b/libraries/shared/src/TriangleSet.h index a838e2d9e2..84e362f0d0 100644 --- a/libraries/shared/src/TriangleSet.h +++ b/libraries/shared/src/TriangleSet.h @@ -19,10 +19,10 @@ class TriangleSet { - class TriangleOctreeCell { + class TriangleTreeCell { public: - TriangleOctreeCell(std::vector& allTriangles) : _allTriangles(allTriangles) {} - TriangleOctreeCell(std::vector& allTriangles, const AABox& bounds, int depth); + TriangleTreeCell(std::vector& allTriangles) : _allTriangles(allTriangles) {} + TriangleTreeCell(std::vector& allTriangles, const AABox& bounds, int depth); void insert(size_t triangleIndex); void reset(const AABox& bounds, int depth = 0); @@ -48,10 +48,10 @@ class TriangleSet { float& parabolicDistance, BoxFace& face, Triangle& triangle, bool precision, int& trianglesTouched, bool allowBackface = false); - std::pair getTriangleOctreeCellChildBounds(); + std::pair getTriangleTreeCellChildBounds(); std::vector& _allTriangles; - std::pair, std::shared_ptr> _children; + std::pair, std::shared_ptr> _children; int _depth { 0 }; int _population { 0 }; AABox _bounds; @@ -60,10 +60,10 @@ class TriangleSet { friend class TriangleSet; }; - using SortedTriangleCell = std::pair>; + using SortedTriangleCell = std::pair>; public: - TriangleSet() : _triangleOctree(_triangles) {} + TriangleSet() : _triangleTree(_triangles) {} void debugDump(); @@ -74,7 +74,7 @@ public: bool findParabolaIntersection(const glm::vec3& origin, const glm::vec3& velocity, const glm::vec3& acceleration, float& parabolicDistance, BoxFace& face, Triangle& triangle, bool precision, bool allowBackface = false); - void balanceOctree(); + void balanceTree(); void reserve(size_t size) { _triangles.reserve(size); } // reserve space in the datastructure for size number of triangles size_t size() const { return _triangles.size(); } @@ -89,6 +89,6 @@ public: protected: bool _isBalanced { false }; std::vector _triangles; - TriangleOctreeCell _triangleOctree; + TriangleTreeCell _triangleTree; AABox _bounds; }; From 1123ba2b0a5bebd92c87ea336655b9a8472b4b39 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 22 Aug 2018 22:48:42 -0700 Subject: [PATCH 079/545] exploring optimization in Backend for bffer bindings --- libraries/gpu-gl-common/src/gpu/gl/GLBackend.h | 1 + .../gpu-gl-common/src/gpu/gl/GLBackendInput.cpp | 17 ++++++++++++----- .../src/gpu/gl/GLBackendPipeline.cpp | 2 ++ libraries/gpu-gl-common/src/gpu/gl/GLBuffer.h | 14 +++++++++++++- libraries/gpu-gl/src/gpu/gl41/GL41Backend.h | 1 + .../gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp | 4 ++++ libraries/gpu-gl/src/gpu/gl45/GL45Backend.h | 1 + .../gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp | 5 +++++ libraries/gpu/src/gpu/Batch.h | 4 ++-- 9 files changed, 41 insertions(+), 8 deletions(-) diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h index cadcec7a56..2fa2df5bfa 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h @@ -239,6 +239,7 @@ public: virtual GLuint getFramebufferID(const FramebufferPointer& framebuffer) = 0; virtual GLuint getTextureID(const TexturePointer& texture) final; virtual GLuint getBufferID(const Buffer& buffer) = 0; + virtual GLuint getBufferIDUnsafe(const Buffer& buffer) = 0; virtual GLuint getQueryID(const QueryPointer& query) = 0; virtual GLFramebuffer* syncGPUObject(const Framebuffer& framebuffer) = 0; diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp index 77e1f90f66..6ce25bc56c 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp @@ -11,6 +11,7 @@ #include "GLBackend.h" #include "GLShared.h" #include "GLInputFormat.h" +#include "GLBuffer.h" using namespace gpu; using namespace gpu::gl; @@ -39,14 +40,20 @@ void GLBackend::do_setInputBuffer(const Batch& batch, size_t paramOffset) { BufferPointer buffer = batch._buffers.get(batch._params[paramOffset + 2]._uint); uint32 channel = batch._params[paramOffset + 3]._uint; - if (channel < getNumInputBuffers()) { + // if (channel < getNumInputBuffers()) { bool isModified = false; if (_input._buffers[channel] != buffer) { _input._buffers[channel] = buffer; GLuint vbo = 0; if (buffer) { - vbo = getBufferID((*buffer)); + // vbo = getBufferID((*buffer)); + // vbo = getBufferIDUnsafe((*buffer)); + auto* object = Backend::getGPUObject((*buffer)); + + if (object) { + vbo = object->_buffer; + } } _input._bufferVBOs[channel] = vbo; @@ -66,7 +73,7 @@ void GLBackend::do_setInputBuffer(const Batch& batch, size_t paramOffset) { if (isModified) { _input._invalidBuffers.set(channel); } - } + // } } void GLBackend::initInput() { @@ -128,7 +135,7 @@ void GLBackend::do_setIndexBuffer(const Batch& batch, size_t paramOffset) { if (indexBuffer != _input._indexBuffer) { _input._indexBuffer = indexBuffer; if (indexBuffer) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, getBufferID(*indexBuffer)); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, getBufferIDUnsafe(*indexBuffer)); } else { // FIXME do we really need this? Is there ever a draw call where we care that the element buffer is null? glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); @@ -145,7 +152,7 @@ void GLBackend::do_setIndirectBuffer(const Batch& batch, size_t paramOffset) { if (buffer != _input._indirectBuffer) { _input._indirectBuffer = buffer; if (buffer) { - glBindBuffer(GL_DRAW_INDIRECT_BUFFER, getBufferID(*buffer)); + glBindBuffer(GL_DRAW_INDIRECT_BUFFER, getBufferIDUnsafe(*buffer)); } else { // FIXME do we really need this? Is there ever a draw call where we care that the element buffer is null? glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0); diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackendPipeline.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendPipeline.cpp index d3d2bc0938..fd67202863 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackendPipeline.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackendPipeline.cpp @@ -172,6 +172,8 @@ void GLBackend::bindUniformBuffer(uint32_t slot, const BufferPointer& buffer, GL // Sync BufferObject auto* object = syncGPUObject(*bufferState.buffer); + // auto glBO = getBufferIDUnsafe(*buffer); + if (object) { glBindBufferRange(GL_UNIFORM_BUFFER, slot, object->_buffer, bufferState.offset, bufferState.size); diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBuffer.h b/libraries/gpu-gl-common/src/gpu/gl/GLBuffer.h index 182014e764..8efbe03b90 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBuffer.h +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBuffer.h @@ -49,13 +49,25 @@ public: } } + template + static GLuint getIdUnsafe(GLBackend& backend, const Buffer& buffer) { + GLBufferType* object = Backend::getGPUObject(buffer); + + if (object) { + return object->_buffer; + } + else { + return 0; + } + } + const GLuint& _buffer { _id }; const GLuint _size; const Stamp _stamp; ~GLBuffer(); - virtual void transfer() = 0; + virtual void transfer() {}; protected: GLBuffer(const std::weak_ptr& backend, const Buffer& buffer, GLuint id); diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h b/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h index c6fbc43ae5..a09b3e9297 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h +++ b/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h @@ -134,6 +134,7 @@ protected: GLFramebuffer* syncGPUObject(const Framebuffer& framebuffer) override; GLuint getBufferID(const Buffer& buffer) override; + GLuint getBufferIDUnsafe(const Buffer& buffer) override; GLuint getResourceBufferID(const Buffer& buffer); GLBuffer* syncGPUObject(const Buffer& buffer) override; diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp index 62ade673b4..97ac2739eb 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp @@ -83,6 +83,10 @@ GLuint GL41Backend::getBufferID(const Buffer& buffer) { return GL41Buffer::getId(*this, buffer); } +GLuint GL41Backend::getBufferIDUnsafe(const Buffer& buffer) { + return GL41Backend::getBufferID(buffer); +} + GLuint GL41Backend::getResourceBufferID(const Buffer& buffer) { auto* object = GL41Buffer::sync(*this, buffer); if (object) { diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h index 658bea2a3e..5da4506773 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h +++ b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h @@ -235,6 +235,7 @@ protected: GLFramebuffer* syncGPUObject(const Framebuffer& framebuffer) override; GLuint getBufferID(const Buffer& buffer) override; + GLuint getBufferIDUnsafe(const Buffer& buffer) override; GLBuffer* syncGPUObject(const Buffer& buffer) override; GLTexture* syncGPUObject(const TexturePointer& texture) override; diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp index 2afbea3876..0d26f8f412 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp @@ -51,6 +51,11 @@ GLuint GL45Backend::getBufferID(const Buffer& buffer) { return GL45Buffer::getId(*this, buffer); } +GLuint GL45Backend::getBufferIDUnsafe(const Buffer& buffer) { + //return GL45Buffer::getId(*this, buffer); + return GL45Buffer::getIdUnsafe(*this, buffer); +} + GLBuffer* GL45Backend::syncGPUObject(const Buffer& buffer) { return GL45Buffer::sync(*this, buffer); } diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index bcbfe0616d..2bead507b8 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -417,10 +417,10 @@ public: } const Data& get(uint32 offset) const { - if (offset >= _items.size()) { + /* if (offset >= _items.size()) { static const Data EMPTY; return EMPTY; - } + }*/ return (_items.data() + offset)->_data; } From e3ad5adcaec07108360e340302cd643c61e4af31 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Thu, 23 Aug 2018 06:49:35 -0700 Subject: [PATCH 080/545] first approach vertical alignment --- libraries/avatars/src/AvatarData.cpp | 2 +- libraries/avatars/src/AvatarData.h | 4 ++ libraries/avatars/src/AvatarHashMap.cpp | 72 +++++++++++++++++++++++-- libraries/avatars/src/AvatarHashMap.h | 2 + 4 files changed, 74 insertions(+), 6 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index c1ec19b307..63a905aa6e 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -918,7 +918,7 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { PACKET_READ_CHECK(AvatarGlobalPosition, sizeof(AvatarDataPacket::AvatarGlobalPosition)); auto data = reinterpret_cast(sourceBuffer); - auto newValue = glm::vec3(data->globalPosition[0], data->globalPosition[1], data->globalPosition[2]); + auto newValue = glm::vec3(data->globalPosition[0], data->globalPosition[1], data->globalPosition[2]) + glm::vec3(0, 2 * _surrogateIndex, 0); if (_globalPosition != newValue) { _globalPosition = newValue; _globalPositionChanged = usecTimestampNow(); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 53a2a69119..b3443dbd8a 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -1186,6 +1186,9 @@ public: virtual void addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName) {} virtual void removeMaterial(graphics::MaterialPointer material, const std::string& parentMaterialName) {} + void setSurrogateIndex(int surrogateIndex) { _surrogateIndex = surrogateIndex; } + int getSurrogateIndex() { return _surrogateIndex; } + signals: /**jsdoc @@ -1443,6 +1446,7 @@ protected: udt::SequenceNumber _identitySequenceNumber { 0 }; bool _hasProcessedFirstIdentity { false }; float _density; + int _surrogateIndex{ 0 }; // null unless MyAvatar or ScriptableAvatar sending traits data to mixer std::unique_ptr _clientTraitsHandler; diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index 64b26131be..a84d83e663 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -21,6 +21,8 @@ #include "AvatarLogging.h" #include "AvatarTraits.h" +const int SURROGATE_COUNT = 2; + AvatarHashMap::AvatarHashMap() { auto nodeList = DependencyManager::get(); @@ -139,14 +141,37 @@ AvatarSharedPointer AvatarHashMap::parseAvatarData(QSharedPointerisIgnoringNode(sessionUUID) || nodeList->getRequestsDomainListData())) { auto avatar = newOrExistingAvatar(sessionUUID, sendingNode, isNewAvatar); + + if (isNewAvatar) { QWriteLocker locker(&_hashLock); _pendingAvatars.insert(sessionUUID, { std::chrono::steady_clock::now(), 0, avatar }); + std::vector surrogateIDs; + for (int i = 0; i < SURROGATE_COUNT; i++) { + QUuid surrogateID = QUuid::createUuid(); + surrogateIDs.push_back(surrogateID); + auto surrogateAvatar = addAvatar(surrogateID, sendingNode); + surrogateAvatar->setSurrogateIndex(i + 1); + surrogateAvatar->parseDataFromBuffer(byteArray); + _pendingAvatars.insert(surrogateID, { std::chrono::steady_clock::now(), 0, surrogateAvatar }); + } + _surrogates.insert(std::pair>(sessionUUID, surrogateIDs)); + } else { + auto surrogateIDs = _surrogates[sessionUUID]; + for (auto id : surrogateIDs) { + auto surrogateAvatar = newOrExistingAvatar(id, sendingNode, isNewAvatar); + if (!isNewAvatar) { + surrogateAvatar->parseDataFromBuffer(byteArray); + } + } + } // have the matching (or new) avatar parse the data from the packet int bytesRead = avatar->parseDataFromBuffer(byteArray); message->seek(positionBeforeRead + bytesRead); + + avatar->parseDataFromBuffer(byteArray); return avatar; } else { // create a dummy AvatarData class to throw this data on the ground @@ -191,13 +216,22 @@ void AvatarHashMap::processAvatarIdentityPacket(QSharedPointer bool displayNameChanged = false; // In this case, the "sendingNode" is the Avatar Mixer. avatar->processAvatarIdentity(message->getMessage(), identityChanged, displayNameChanged); + auto surrogateIDs = _surrogates[identityUUID]; + for (auto id : surrogateIDs) { + auto surrogateAvatar = newOrExistingAvatar(id, sendingNode, isNewAvatar); + if (!isNewAvatar) { + surrogateAvatar->processAvatarIdentity(message->getMessage(), identityChanged, displayNameChanged); + } + } } } -void AvatarHashMap::processBulkAvatarTraits(QSharedPointer message, SharedNodePointer sendingNode) { +void AvatarHashMap::processAvatarTraits(QUuid sessionUUID, QSharedPointer message, SharedNodePointer sendingNode) { + message->seek(0); while (message->getBytesLeftToRead()) { // read the avatar ID to figure out which avatar this is for auto avatarID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); + avatarID = sessionUUID; // grab the avatar so we can ask it to process trait data bool isNewAvatar; @@ -225,10 +259,12 @@ void AvatarHashMap::processBulkAvatarTraits(QSharedPointer mess if (packetTraitVersion > lastProcessedVersions[traitType]) { avatar->processTrait(traitType, message->read(traitBinarySize)); lastProcessedVersions[traitType] = packetTraitVersion; - } else { + } + else { skipBinaryTrait = true; } - } else { + } + else { AvatarTraits::TraitInstanceID traitInstanceID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); @@ -238,11 +274,13 @@ void AvatarHashMap::processBulkAvatarTraits(QSharedPointer mess if (packetTraitVersion > processedInstanceVersion) { if (traitBinarySize == AvatarTraits::DELETED_TRAIT_SIZE) { avatar->processDeletedTraitInstance(traitType, traitInstanceID); - } else { + } + else { avatar->processTraitInstance(traitType, traitInstanceID, message->read(traitBinarySize)); } processedInstanceVersion = packetTraitVersion; - } else { + } + else { skipBinaryTrait = true; } } @@ -258,6 +296,18 @@ void AvatarHashMap::processBulkAvatarTraits(QSharedPointer mess } } +void AvatarHashMap::processBulkAvatarTraits(QSharedPointer message, SharedNodePointer sendingNode) { + while (message->getBytesLeftToRead()) { + // read the avatar ID to figure out which avatar this is for + auto avatarID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); + processAvatarTraits(avatarID, message, sendingNode); + auto surrogateIDs = _surrogates[avatarID]; + for (auto id : surrogateIDs) { + processAvatarTraits(id, message, sendingNode); + } + } +} + void AvatarHashMap::processKillAvatar(QSharedPointer message, SharedNodePointer sendingNode) { // read the node id QUuid sessionUUID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); @@ -265,6 +315,10 @@ void AvatarHashMap::processKillAvatar(QSharedPointer message, S KillAvatarReason reason; message->readPrimitive(&reason); removeAvatar(sessionUUID, reason); + auto surrogateIDs = _surrogates[sessionUUID]; + for (auto id : surrogateIDs) { + removeAvatar(id, reason); + } } void AvatarHashMap::removeAvatar(const QUuid& sessionUUID, KillAvatarReason removalReason) { @@ -276,6 +330,14 @@ void AvatarHashMap::removeAvatar(const QUuid& sessionUUID, KillAvatarReason remo if (removedAvatar) { handleRemovedAvatar(removedAvatar, removalReason); } + auto surrogateIDs = _surrogates[sessionUUID]; + for (auto id : surrogateIDs) { + _pendingAvatars.remove(id); + auto removedSurrogate = _avatarHash.take(id); + if (removedSurrogate) { + handleRemovedAvatar(removedSurrogate, removalReason); + } + } } void AvatarHashMap::handleRemovedAvatar(const AvatarSharedPointer& removedAvatar, KillAvatarReason removalReason) { diff --git a/libraries/avatars/src/AvatarHashMap.h b/libraries/avatars/src/AvatarHashMap.h index ba16fa9568..41981df693 100644 --- a/libraries/avatars/src/AvatarHashMap.h +++ b/libraries/avatars/src/AvatarHashMap.h @@ -134,6 +134,7 @@ protected slots: */ void processAvatarIdentityPacket(QSharedPointer message, SharedNodePointer sendingNode); + void processAvatarTraits(QUuid sessionUUID, QSharedPointer message, SharedNodePointer sendingNode); void processBulkAvatarTraits(QSharedPointer message, SharedNodePointer sendingNode); /**jsdoc @@ -167,6 +168,7 @@ protected: mutable QReadWriteLock _hashLock; std::unordered_map _processedTraitVersions; + std::map> _surrogates; private: QUuid _lastOwnerSessionUUID; }; From 30ef544c6debac94cf1df5a0f5ee714c029143a9 Mon Sep 17 00:00:00 2001 From: Angus Antley Date: Thu, 23 Aug 2018 15:57:14 +0100 Subject: [PATCH 081/545] starting the c++ version of shoulder rotation --- interface/src/avatar/MyAvatar.cpp | 11 +++++++++++ interface/src/avatar/MyAvatar.h | 5 +++++ 2 files changed, 16 insertions(+) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 44ee5e30c6..6211e6f0d8 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -801,6 +801,17 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { } } +void MyAvatar::computeHandAzimuth() { + controller::Pose leftHandPoseAvatarSpace = getLeftHandPose(); + controller::Pose rightHandPoseAvatarSpace = getRightHandPose(); + glm::vec3 localLookat(0.0f, 0.0f, 1.0f); + glm::vec3 rightHandRigSpace = rightHandPoseAvatarSpace.rotation * localLookat; + glm::vec3 lefttHandRigSpace = leftHandPoseAvatarSpace.rotation * localLookat; + + _hipToHandController = glm::vec2(rightHandRigSpace.x, rightHandRigSpace.z); + +} + void MyAvatar::updateJointFromController(controller::Action poseKey, ThreadSafeValueCache& matrixCache) { assert(QThread::currentThread() == thread()); auto userInputMapper = DependencyManager::get(); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 10b5884d5a..6b7c4e83a1 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -320,6 +320,9 @@ public: // as it moves through the world. void updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix); + // compute the hip to hand average azimuth. + void computeHandAzimuth(); + // read the location of a hand controller and save the transform void updateJointFromController(controller::Action poseKey, ThreadSafeValueCache& matrixCache); @@ -1658,6 +1661,8 @@ private: glm::vec2 _headControllerFacingMovingAverage { 0.0f, 0.0f }; // facing vector in xz plane (sensor space) glm::quat _averageHeadRotation { 0.0f, 0.0f, 0.0f, 1.0f }; + glm::vec2 _hipToHandController; // facing vector in xz plane (sensor space) + float _currentStandingHeight { 0.0f }; bool _resetMode { true }; RingBufferHistory _recentModeReadings; From 473f8d0ca5918bc8b8fc3ff322ec0a527809cc3f Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 23 Aug 2018 11:39:47 -0700 Subject: [PATCH 082/545] Working on the LOD system --- interface/resources/qml/+android/Stats.qml | 15 ++++ interface/resources/qml/Stats.qml | 17 ++++ interface/src/LODManager.cpp | 7 ++ interface/src/LODManager.h | 10 ++- interface/src/ui/Stats.cpp | 6 ++ interface/src/ui/Stats.h | 13 ++- .../render/configSlider/ConfigSlider.qml | 6 +- scripts/developer/utilities/render/lod.js | 88 +++++++++++++++---- scripts/developer/utilities/render/lod.qml | 60 ++++++++++++- 9 files changed, 198 insertions(+), 24 deletions(-) diff --git a/interface/resources/qml/+android/Stats.qml b/interface/resources/qml/+android/Stats.qml index fe827f6ece..0dcb07e730 100644 --- a/interface/resources/qml/+android/Stats.qml +++ b/interface/resources/qml/+android/Stats.qml @@ -264,20 +264,27 @@ Item { StatText { text: "GPU: " + root.gpuFrameTime.toFixed(1) + " ms" } + StatText { + text: "Drawcalls: " + root.drawcalls + } StatText { text: "Triangles: " + root.triangles + " / Material Switches: " + root.materialSwitches } StatText { + visible: root.expanded; text: "GPU Free Memory: " + root.gpuFreeMemory + " MB"; } StatText { + visible: root.expanded; text: "GPU Textures: "; } StatText { + visible: root.expanded; text: " Count: " + root.gpuTextures; } StatText { + visible: root.expanded; text: " Pressure State: " + root.gpuTextureMemoryPressureState; } StatText { @@ -287,27 +294,35 @@ Item { text: " " + root.gpuTextureResourceMemory + " / " + root.gpuTextureResourcePopulatedMemory + " / " + root.texturePendingTransfers + " MB"; } StatText { + visible: root.expanded; text: " Resident Memory: " + root.gpuTextureResidentMemory + " MB"; } StatText { + visible: root.expanded; text: " Framebuffer Memory: " + root.gpuTextureFramebufferMemory + " MB"; } StatText { + visible: root.expanded; text: " External Memory: " + root.gpuTextureExternalMemory + " MB"; } StatText { + visible: root.expanded; text: "GPU Buffers: " } StatText { + visible: root.expanded; text: " Count: " + root.gpuBuffers; } StatText { + visible: root.expanded; text: " Memory: " + root.gpuBufferMemory + " MB"; } StatText { + visible: root.expanded; text: "GL Swapchain Memory: " + root.glContextSwapchainMemory + " MB"; } StatText { + visible: root.expanded; text: "QML Texture Memory: " + root.qmlTextureMemory + " MB"; } StatText { diff --git a/interface/resources/qml/Stats.qml b/interface/resources/qml/Stats.qml index 2e6e909312..574ceb62a4 100644 --- a/interface/resources/qml/Stats.qml +++ b/interface/resources/qml/Stats.qml @@ -285,52 +285,69 @@ Item { StatText { text: "GPU frame size: " + root.gpuFrameSize.x + " x " + root.gpuFrameSize.y } + StatText { + text: "Drawcalls: " + root.drawcalls + } StatText { text: "Triangles: " + root.triangles + " / Material Switches: " + root.materialSwitches } StatText { + visible: root.expanded; text: "GPU Free Memory: " + root.gpuFreeMemory + " MB"; } StatText { + visible: root.expanded; text: "GPU Textures: "; } StatText { + visible: root.expanded; text: " Count: " + root.gpuTextures; } StatText { + visible: root.expanded; text: " Pressure State: " + root.gpuTextureMemoryPressureState; } StatText { + visible: root.expanded; property bool showIdeal: (root.gpuTextureResourceIdealMemory != root.gpuTextureResourceMemory); text: " Resource Allocated " + (showIdeal ? "(Ideal)" : "") + " / Populated / Pending: "; } StatText { + visible: root.expanded; property bool showIdeal: (root.gpuTextureResourceIdealMemory != root.gpuTextureResourceMemory); text: " " + root.gpuTextureResourceMemory + (showIdeal ? ("(" + root.gpuTextureResourceIdealMemory + ")") : "") + " / " + root.gpuTextureResourcePopulatedMemory + " / " + root.texturePendingTransfers + " MB"; } StatText { + visible: root.expanded; text: " Resident Memory: " + root.gpuTextureResidentMemory + " MB"; } StatText { + visible: root.expanded; text: " Framebuffer Memory: " + root.gpuTextureFramebufferMemory + " MB"; } StatText { + visible: root.expanded; text: " External Memory: " + root.gpuTextureExternalMemory + " MB"; } StatText { + visible: root.expanded; text: "GPU Buffers: " } StatText { + visible: root.expanded; text: " Count: " + root.gpuBuffers; } StatText { + visible: root.expanded; text: " Memory: " + root.gpuBufferMemory + " MB"; } StatText { + visible: root.expanded; text: "GL Swapchain Memory: " + root.glContextSwapchainMemory + " MB"; } StatText { + visible: root.expanded; text: "QML Texture Memory: " + root.qmlTextureMemory + " MB"; } StatText { diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index da1f14c450..681bdaf884 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -87,6 +87,7 @@ void LODManager::autoAdjustLOD(float realTimeDelta) { _octreeSizeScale = ADJUST_LOD_MIN_SIZE_SCALE; } emit LODDecreased(); + emit LODChanged(); // Assuming the LOD adjustment will work: we optimistically reset _avgRenderTime // to provide an FPS just above the decrease threshold. It will drift close to its // true value after a few LOD_ADJUST_TIMESCALEs and we'll adjust again as necessary. @@ -108,6 +109,8 @@ void LODManager::autoAdjustLOD(float realTimeDelta) { _octreeSizeScale = ADJUST_LOD_MAX_SIZE_SCALE; } emit LODIncreased(); + emit LODChanged(); + // Assuming the LOD adjustment will work: we optimistically reset _avgRenderTime // to provide an FPS just below the increase threshold. It will drift close to its // true value after a few LOD_ADJUST_TIMESCALEs and we'll adjust again as necessary. @@ -145,6 +148,10 @@ float LODManager::getLODLevel() const { return simpleLOD; } +void LODManager::setLODLevel(float level) { + +} + const float MIN_DECREASE_FPS = 0.5f; void LODManager::setDesktopLODDecreaseFPS(float fps) { diff --git a/interface/src/LODManager.h b/interface/src/LODManager.h index 8f88da63a8..f0bc1aabf9 100644 --- a/interface/src/LODManager.h +++ b/interface/src/LODManager.h @@ -30,7 +30,9 @@ const float INCREASE_LOD_GAP_FPS = 10.0f; // fps // The default value DEFAULT_OCTREE_SIZE_SCALE means you can be 400 meters away from a 1 meter object in order to see it (which is ~20:20 vision). const float ADJUST_LOD_MAX_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE; // This controls how low the auto-adjust LOD will go. We want a minimum vision of ~20:500 or 0.04 of default -const float ADJUST_LOD_MIN_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE * 0.04f; +// const float ADJUST_LOD_MIN_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE * 0.04f; +// const float ADJUST_LOD_MIN_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE * 0.02f; +const float ADJUST_LOD_MIN_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE * 0.01f; class AABox; @@ -60,9 +62,10 @@ class LODManager : public QObject, public Dependency { Q_PROPERTY(float gpuTime READ getGPUTime) Q_PROPERTY(float avgRenderTime READ getAverageRenderTime) Q_PROPERTY(float fps READ getMaxTheoreticalFPS) - Q_PROPERTY(float lodLevel READ getLODLevel) + Q_PROPERTY(float lodLevel READ getLODLevel WRITE setLODLevel NOTIFY LODChanged) Q_PROPERTY(float lodDecreaseFPS READ getLODDecreaseFPS) Q_PROPERTY(float lodIncreaseFPS READ getLODIncreaseFPS) + Q_PROPERTY(bool automaticLODAdjust READ getAutomaticLODAdjust WRITE setAutomaticLODAdjust) public: @@ -174,6 +177,7 @@ public: float getAverageRenderTime() const { return _avgRenderTime; }; float getMaxTheoreticalFPS() const { return (float)MSECS_PER_SECOND / _avgRenderTime; }; float getLODLevel() const; + void setLODLevel(float level); signals: @@ -189,6 +193,8 @@ signals: */ void LODDecreased(); + void LODChanged(); + private: LODManager(); diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index ce1cd51de1..912e851c00 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -376,6 +376,12 @@ void Stats::updateStats(bool force) { STAT_UPDATE(rectifiedTextureCount, (int)RECTIFIED_TEXTURE_COUNT.load()); STAT_UPDATE(decimatedTextureCount, (int)DECIMATED_TEXTURE_COUNT.load()); + gpu::ContextStats gpuFrameStats; + gpuContext->getFrameStats(gpuFrameStats); + + STAT_UPDATE(drawcalls, gpuFrameStats._DSNumDrawcalls); + + // Incoming packets QLocale locale(QLocale::English); auto voxelPacketsToProcess = qApp->getOctreePacketProcessor().packetsToProcessCount(); diff --git a/interface/src/ui/Stats.h b/interface/src/ui/Stats.h index cf624b54c3..f9043f8f56 100644 --- a/interface/src/ui/Stats.h +++ b/interface/src/ui/Stats.h @@ -239,7 +239,8 @@ class Stats : public QQuickItem { STATS_PROPERTY(int, processing, 0) STATS_PROPERTY(int, processingPending, 0) STATS_PROPERTY(int, triangles, 0) - STATS_PROPERTY(int, quads, 0) + STATS_PROPERTY(int, drawcalls, 0) + // STATS_PROPERTY(int, quads, 0) STATS_PROPERTY(int, materialSwitches, 0) STATS_PROPERTY(int, itemConsidered, 0) STATS_PROPERTY(int, itemOutOfView, 0) @@ -708,12 +709,20 @@ signals: */ void trianglesChanged(); + /**jsdoc + * Triggered when the value of the drawcalls property changes. + * This + * @function Stats.drawcallsChanged + * @returns {Signal} + */ + void drawcallsChanged(); + /**jsdoc * Triggered when the value of the quads property changes. * @function Stats.quadsChanged * @returns {Signal} */ - void quadsChanged(); + // void quadsChanged(); /**jsdoc * Triggered when the value of the materialSwitches property changes. diff --git a/scripts/developer/utilities/render/configSlider/ConfigSlider.qml b/scripts/developer/utilities/render/configSlider/ConfigSlider.qml index 41de77fb09..345b29e791 100644 --- a/scripts/developer/utilities/render/configSlider/ConfigSlider.qml +++ b/scripts/developer/utilities/render/configSlider/ConfigSlider.qml @@ -56,13 +56,13 @@ Item { anchors.verticalCenter: root.verticalCenter } - Binding { + /* Binding { id: bindingControl target: root.config property: root.property value: sliderControl.value when: false - } + }*/ HifiControls.Slider { id: sliderControl @@ -73,7 +73,7 @@ Item { anchors.top: root.top anchors.topMargin: 0 - onValueChanged: { root.valueChanged(value) } + // onValueChanged: { root.valueChanged(value) } } HifiControls.Label { diff --git a/scripts/developer/utilities/render/lod.js b/scripts/developer/utilities/render/lod.js index 307e509d39..632f4e50c5 100644 --- a/scripts/developer/utilities/render/lod.js +++ b/scripts/developer/utilities/render/lod.js @@ -16,15 +16,9 @@ var ICON_URL = Script.resolvePath("../../../system/assets/images/lod-i.svg"); var ACTIVE_ICON_URL = Script.resolvePath("../../../system/assets/images/lod-a.svg"); - var onScreen = false; + var onTablet = false; // set this to true to use the tablet, false use a floating window - function onClicked() { - if (onScreen) { - tablet.gotoHomeScreen(); - } else { - tablet.loadQMLSource(QMLAPP_URL); - } - } + var onAppScreen = false; var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); var button = tablet.addButton({ @@ -35,6 +29,51 @@ var hasEventBridge = false; + var onScreen = false; + var window; + + function onClicked() { + if (onTablet) { + if (onAppScreen) { + tablet.gotoHomeScreen(); + } else { + tablet.loadQMLSource(QMLAPP_URL); + } + } else { + if (onScreen) { + killWindow() + } else { + createWindow() + } + } + } + + function createWindow() { + var qml = Script.resolvePath(QMLAPP_URL); + window = Desktop.createWindow(Script.resolvePath(QMLAPP_URL), { + title: TABLET_BUTTON_NAME, + flags: Desktop.ALWAYS_ON_TOP, + presentationMode: Desktop.PresentationMode.NATIVE, + size: {x: 400, y: 600} + }); + // window.setPosition(200, 50); + window.closed.connect(killWindow); + window.fromQml.connect(fromQml); + onScreen = true + button.editProperties({isActive: true}); + } + + function killWindow() { + if (window !== undefined) { + window.closed.disconnect(killWindow); + window.fromQml.disconnect(fromQml); + window.close() + window = undefined + } + onScreen = false + button.editProperties({isActive: false}) + } + function wireEventBridge(on) { if (!tablet) { print("Warning in wireEventBridge(): 'tablet' undefined!"); @@ -54,23 +93,42 @@ } function onScreenChanged(type, url) { - onScreen = (url === QMLAPP_URL); - button.editProperties({isActive: onScreen}); - wireEventBridge(onScreen); - } - - function fromQml(message) { + if (onTablet) { + if (url === QMLAPP_URL) { + onAppScreen = true; + } else { + onAppScreen = false; + } + + button.editProperties({isActive: onAppScreen}); + wireEventBridge(onAppScreen); + } } button.clicked.connect(onClicked); tablet.screenChanged.connect(onScreenChanged); Script.scriptEnding.connect(function () { - if (onScreen) { + killWindow() + if (onAppScreen) { tablet.gotoHomeScreen(); } button.clicked.disconnect(onClicked); tablet.screenChanged.disconnect(onScreenChanged); tablet.removeButton(button); }); + + function fromQml(message) { + } + + function sendToQml(message) { + if (onTablet) { + tablet.sendToQml(message); + } else { + if (window) { + window.sendToQml(message); + } + } + } + }()); diff --git a/scripts/developer/utilities/render/lod.qml b/scripts/developer/utilities/render/lod.qml index d7b9f1cd57..36a19c10f2 100644 --- a/scripts/developer/utilities/render/lod.qml +++ b/scripts/developer/utilities/render/lod.qml @@ -10,20 +10,73 @@ // import QtQuick 2.5 import QtQuick.Controls 1.4 + +import "qrc:///qml/styles-uit" +import "qrc:///qml/controls-uit" as HifiControls + import "../lib/plotperf" +import "configSlider" Item { id: lodIU anchors.fill:parent + Component.onCompleted: { + Render.getConfig("RenderMainView.DrawSceneOctree").showVisibleCells = false + Render.getConfig("RenderMainView.DrawSceneOctree").showEmptyCells = false + } + + Component.onDestruction: { + Render.getConfig("RenderMainView.DrawSceneOctree").enabled = false + } + + Column { + id: topHeader + spacing: 8 + anchors.right: parent.right + anchors.left: parent.left + + HifiControls.CheckBox { + boxSize: 20 + text: "Show LOD Reticule" + checked: Render.getConfig("RenderMainView.DrawSceneOctree").enabled + onCheckedChanged: { Render.getConfig("RenderMainView.DrawSceneOctree").enabled = checked } + } + HifiControls.CheckBox { + boxSize: 20 + text: "Manual LOD" + checked: LODManager.getAutomaticLODAdjust() + onCheckedChanged: { LODManager.setAutomaticLODAdjust(checked) } + } + ConfigSlider { + showLabel: true + config: LODManager + property: "lodLevel" + max: 13 + min: 0 + integral: false + + anchors.left: parent.left + anchors.right: parent.right + } + + } + Column { id: stats spacing: 8 - anchors.fill:parent + anchors.right: parent.right + anchors.left: parent.left + anchors.top: topHeader.bottom + anchors.bottom: parent.bottom function evalEvenHeight() { // Why do we have to do that manually ? cannot seem to find a qml / anchor / layout mode that does that ? - return (height - spacing * (children.length - 1)) / children.length + return (height - topLine.height - bottomLine.height - spacing * (children.length - 3)) / (children.length - 2) + } + + Separator { + id: topLine } PlotPerf { @@ -87,6 +140,9 @@ Item { color: "#9999FF" } ] + } + Separator { + id: bottomLine } } } From 3d959ca7ee6c59496f30dc15f6da02f666376166 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Thu, 23 Aug 2018 15:52:42 -0700 Subject: [PATCH 083/545] Refactoring and cleaning --- .../src/avatars-renderer/Avatar.h | 1 - libraries/avatars/src/AvatarData.cpp | 21 +- libraries/avatars/src/AvatarData.h | 8 +- libraries/avatars/src/AvatarHashMap.cpp | 223 ++++++++++++++---- libraries/avatars/src/AvatarHashMap.h | 23 +- 5 files changed, 223 insertions(+), 53 deletions(-) diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h index c6e8ac59f1..63aa6d9b6f 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h @@ -464,7 +464,6 @@ protected: glm::vec3 _lastAngularVelocity; glm::vec3 _angularAcceleration; glm::quat _lastOrientation; - glm::vec3 _worldUpDirection { Vectors::UP }; bool _moving { false }; ///< set when position is changing diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 63a905aa6e..ddb53f8acb 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -918,7 +918,26 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { PACKET_READ_CHECK(AvatarGlobalPosition, sizeof(AvatarDataPacket::AvatarGlobalPosition)); auto data = reinterpret_cast(sourceBuffer); - auto newValue = glm::vec3(data->globalPosition[0], data->globalPosition[1], data->globalPosition[2]) + glm::vec3(0, 2 * _surrogateIndex, 0); + + const float SPACE_BETWEEN_AVATARS = 2.0f; + const int RANDOM_RADIUS = 100; + const int AVATARS_PER_ROW = 3; + + glm::vec3 offset; + + if (false) { + qsrand(static_cast(getID().toByteArray().toInt())); + float xrand = float((qrand() % ((RANDOM_RADIUS + 1) - 10) + 10) / 10.0f); + float yrand = float((qrand() % ((RANDOM_RADIUS + 1) - 10) + 10) / 10.0f); + offset = glm::vec3(xrand, 0.0f, yrand); + } + else { + int row = _replicaIndex % AVATARS_PER_ROW; + int col = floor(_replicaIndex / AVATARS_PER_ROW); + offset = glm::vec3(row * SPACE_BETWEEN_AVATARS, 0.0f, col * SPACE_BETWEEN_AVATARS); + } + + auto newValue = glm::vec3(data->globalPosition[0], data->globalPosition[1], data->globalPosition[2]) + offset; if (_globalPosition != newValue) { _globalPosition = newValue; _globalPositionChanged = usecTimestampNow(); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index b3443dbd8a..36cc0f936d 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -337,6 +337,7 @@ enum KillAvatarReason : uint8_t { TheirAvatarEnteredYourBubble, YourAvatarEnteredTheirBubble }; + Q_DECLARE_METATYPE(KillAvatarReason); class QDataStream; @@ -1185,9 +1186,8 @@ public: virtual void addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName) {} virtual void removeMaterial(graphics::MaterialPointer material, const std::string& parentMaterialName) {} - - void setSurrogateIndex(int surrogateIndex) { _surrogateIndex = surrogateIndex; } - int getSurrogateIndex() { return _surrogateIndex; } + void setReplicaIndex(int replicaIndex) { _replicaIndex = replicaIndex; } + int getReplicaIndex() { return _replicaIndex; } signals: @@ -1446,7 +1446,7 @@ protected: udt::SequenceNumber _identitySequenceNumber { 0 }; bool _hasProcessedFirstIdentity { false }; float _density; - int _surrogateIndex{ 0 }; + int _replicaIndex { 0 }; // null unless MyAvatar or ScriptableAvatar sending traits data to mixer std::unique_ptr _clientTraitsHandler; diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index a84d83e663..800825f574 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -21,7 +21,80 @@ #include "AvatarLogging.h" #include "AvatarTraits.h" -const int SURROGATE_COUNT = 2; + +void AvatarReplicas::addReplica(const QUuid& parentID, AvatarSharedPointer replica) { + if (_replicasMap.find(parentID) == _replicasMap.end()) { + std::vector emptyReplicas = std::vector(); + _replicasMap.insert(std::pair>(parentID, emptyReplicas)); + } + auto &replicas = _replicasMap[parentID]; + replica->setReplicaIndex((int)replicas.size() + 1); + replicas.push_back(replica); +} + +std::vector AvatarReplicas::getReplicaIDs(const QUuid& parentID, int count) { + std::vector ids; + if (_replicasMap.find(parentID) != _replicasMap.end()) { + auto &replicas = _replicasMap[parentID]; + for (int i = 0; i < replicas.size(); i++) { + ids.push_back(replicas[i]->getID()); + } + } else if (count > 0) { + for (int i = 0; i < count; i++) { + ids.push_back(QUuid::createUuid()); + } + } + return ids; +} + +void AvatarReplicas::parseDataFromBuffer(const QUuid& parentID, const QByteArray& buffer) { + if (_replicasMap.find(parentID) != _replicasMap.end()) { + auto &replicas = _replicasMap[parentID]; + for (auto avatar : replicas) { + avatar->parseDataFromBuffer(buffer); + } + } +} + +void AvatarReplicas::removeReplicas(const QUuid& parentID) { + if (_replicasMap.find(parentID) != _replicasMap.end()) { + _replicasMap.erase(parentID); + } +} + +void AvatarReplicas::processAvatarIdentity(const QUuid& parentID, const QByteArray& identityData, bool& identityChanged, bool& displayNameChanged) { + if (_replicasMap.find(parentID) != _replicasMap.end()) { + auto &replicas = _replicasMap[parentID]; + for (auto avatar : replicas) { + avatar->processAvatarIdentity(identityData, identityChanged, displayNameChanged); + } + } +} +void AvatarReplicas::processTrait(const QUuid& parentID, AvatarTraits::TraitType traitType, QByteArray traitBinaryData) { + if (_replicasMap.find(parentID) != _replicasMap.end()) { + auto &replicas = _replicasMap[parentID]; + for (auto avatar : replicas) { + avatar->processTrait(traitType, traitBinaryData); + } + } +} +void AvatarReplicas::processDeletedTraitInstance(const QUuid& parentID, AvatarTraits::TraitType traitType, AvatarTraits::TraitInstanceID instanceID) { + if (_replicasMap.find(parentID) != _replicasMap.end()) { + auto &replicas = _replicasMap[parentID]; + for (auto avatar : replicas) { + avatar->processDeletedTraitInstance(traitType, instanceID); + } + } +} +void AvatarReplicas::processTraitInstance(const QUuid& parentID, AvatarTraits::TraitType traitType, + AvatarTraits::TraitInstanceID instanceID, QByteArray traitBinaryData) { + if (_replicasMap.find(parentID) != _replicasMap.end()) { + auto &replicas = _replicasMap[parentID]; + for (auto avatar : replicas) { + avatar->processTraitInstance(traitType, instanceID, traitBinaryData); + } + } +} AvatarHashMap::AvatarHashMap() { auto nodeList = DependencyManager::get(); @@ -138,40 +211,28 @@ AvatarSharedPointer AvatarHashMap::parseAvatarData(QSharedPointer(); + const int REPLICAS_COUNT = 8; + bool isNewAvatar; if (sessionUUID != _lastOwnerSessionUUID && (!nodeList->isIgnoringNode(sessionUUID) || nodeList->getRequestsDomainListData())) { auto avatar = newOrExistingAvatar(sessionUUID, sendingNode, isNewAvatar); - - + if (isNewAvatar) { QWriteLocker locker(&_hashLock); _pendingAvatars.insert(sessionUUID, { std::chrono::steady_clock::now(), 0, avatar }); - std::vector surrogateIDs; - for (int i = 0; i < SURROGATE_COUNT; i++) { - QUuid surrogateID = QUuid::createUuid(); - surrogateIDs.push_back(surrogateID); - auto surrogateAvatar = addAvatar(surrogateID, sendingNode); - surrogateAvatar->setSurrogateIndex(i + 1); - surrogateAvatar->parseDataFromBuffer(byteArray); - _pendingAvatars.insert(surrogateID, { std::chrono::steady_clock::now(), 0, surrogateAvatar }); + auto replicaIDs = _replicas.getReplicaIDs(sessionUUID, REPLICAS_COUNT); + for (auto replicaID : replicaIDs) { + auto replicaAvatar = addAvatar(replicaID, sendingNode); + _replicas.addReplica(sessionUUID, replicaAvatar); + _pendingAvatars.insert(replicaID, { std::chrono::steady_clock::now(), 0, replicaAvatar }); } - _surrogates.insert(std::pair>(sessionUUID, surrogateIDs)); - } else { - auto surrogateIDs = _surrogates[sessionUUID]; - for (auto id : surrogateIDs) { - auto surrogateAvatar = newOrExistingAvatar(id, sendingNode, isNewAvatar); - if (!isNewAvatar) { - surrogateAvatar->parseDataFromBuffer(byteArray); - } - } - - } + } // have the matching (or new) avatar parse the data from the packet int bytesRead = avatar->parseDataFromBuffer(byteArray); message->seek(positionBeforeRead + bytesRead); + _replicas.parseDataFromBuffer(sessionUUID, byteArray); - avatar->parseDataFromBuffer(byteArray); return avatar; } else { // create a dummy AvatarData class to throw this data on the ground @@ -216,17 +277,11 @@ void AvatarHashMap::processAvatarIdentityPacket(QSharedPointer bool displayNameChanged = false; // In this case, the "sendingNode" is the Avatar Mixer. avatar->processAvatarIdentity(message->getMessage(), identityChanged, displayNameChanged); - auto surrogateIDs = _surrogates[identityUUID]; - for (auto id : surrogateIDs) { - auto surrogateAvatar = newOrExistingAvatar(id, sendingNode, isNewAvatar); - if (!isNewAvatar) { - surrogateAvatar->processAvatarIdentity(message->getMessage(), identityChanged, displayNameChanged); - } - } + _replicas.processAvatarIdentity(identityUUID, message->getMessage(), identityChanged, displayNameChanged); } } -void AvatarHashMap::processAvatarTraits(QUuid sessionUUID, QSharedPointer message, SharedNodePointer sendingNode) { +void AvatarHashMap::processBulkAvatarTraitsForID(QUuid sessionUUID, QSharedPointer message, SharedNodePointer sendingNode) { message->seek(0); while (message->getBytesLeftToRead()) { // read the avatar ID to figure out which avatar this is for @@ -297,13 +352,88 @@ void AvatarHashMap::processAvatarTraits(QUuid sessionUUID, QSharedPointer message, SharedNodePointer sendingNode) { + /* while (message->getBytesLeftToRead()) { // read the avatar ID to figure out which avatar this is for auto avatarID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); - processAvatarTraits(avatarID, message, sendingNode); - auto surrogateIDs = _surrogates[avatarID]; - for (auto id : surrogateIDs) { - processAvatarTraits(id, message, sendingNode); + processBulkAvatarTraitsForID(avatarID, message, sendingNode); + auto replicaIDs = _replicas.getReplicaIDs(avatarID); + for (auto id : replicaIDs) { + processBulkAvatarTraitsForID(id, message, sendingNode); + } + } + */ + int position = 0; + while (message->getBytesLeftToRead()) { + // read the avatar ID to figure out which avatar this is for + auto avatarID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); + + // grab the avatar so we can ask it to process trait data + bool isNewAvatar; + auto avatar = newOrExistingAvatar(avatarID, sendingNode, isNewAvatar); + + // read the first trait type for this avatar + AvatarTraits::TraitType traitType; + message->readPrimitive(&traitType); + + // grab the last trait versions for this avatar + auto& lastProcessedVersions = _processedTraitVersions[avatarID]; + + while (traitType != AvatarTraits::NullTrait) { + AvatarTraits::TraitVersion packetTraitVersion; + message->readPrimitive(&packetTraitVersion); + + AvatarTraits::TraitWireSize traitBinarySize; + bool skipBinaryTrait = false; + + + if (AvatarTraits::isSimpleTrait(traitType)) { + message->readPrimitive(&traitBinarySize); + + // check if this trait version is newer than what we already have for this avatar + if (packetTraitVersion > lastProcessedVersions[traitType]) { + position = message->getPosition(); + avatar->processTrait(traitType, message->read(traitBinarySize)); + message->seek(position); + _replicas.processTrait(avatarID, traitType, message->read(traitBinarySize)); + lastProcessedVersions[traitType] = packetTraitVersion; + } + else { + skipBinaryTrait = true; + } + } + else { + AvatarTraits::TraitInstanceID traitInstanceID = + QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); + + message->readPrimitive(&traitBinarySize); + + auto& processedInstanceVersion = lastProcessedVersions.getInstanceValueRef(traitType, traitInstanceID); + if (packetTraitVersion > processedInstanceVersion) { + if (traitBinarySize == AvatarTraits::DELETED_TRAIT_SIZE) { + avatar->processDeletedTraitInstance(traitType, traitInstanceID); + _replicas.processDeletedTraitInstance(avatarID, traitType, traitInstanceID); + } + else { + position = message->getPosition(); + avatar->processTraitInstance(traitType, traitInstanceID, message->read(traitBinarySize)); + message->seek(position); + _replicas.processTraitInstance(avatarID, traitType, traitInstanceID, message->read(traitBinarySize)); + } + processedInstanceVersion = packetTraitVersion; + } + else { + skipBinaryTrait = true; + } + } + + if (skipBinaryTrait) { + // we didn't read this trait because it was older or because we didn't have an avatar to process it for + message->seek(message->getPosition() + traitBinarySize); + } + + // read the next trait type, which is null if there are no more traits for this avatar + message->readPrimitive(&traitType); } } } @@ -315,8 +445,8 @@ void AvatarHashMap::processKillAvatar(QSharedPointer message, S KillAvatarReason reason; message->readPrimitive(&reason); removeAvatar(sessionUUID, reason); - auto surrogateIDs = _surrogates[sessionUUID]; - for (auto id : surrogateIDs) { + auto replicaIDs = _replicas.getReplicaIDs(sessionUUID); + for (auto id : replicaIDs) { removeAvatar(id, reason); } } @@ -324,20 +454,23 @@ void AvatarHashMap::processKillAvatar(QSharedPointer message, S void AvatarHashMap::removeAvatar(const QUuid& sessionUUID, KillAvatarReason removalReason) { QWriteLocker locker(&_hashLock); + auto replicaIDs = _replicas.getReplicaIDs(sessionUUID); + _replicas.removeReplicas(sessionUUID); + for (auto id : replicaIDs) { + _pendingAvatars.remove(id); + auto removedReplica = _avatarHash.take(id); + if (removedReplica) { + handleRemovedAvatar(removedReplica, removalReason); + } + } + _pendingAvatars.remove(sessionUUID); auto removedAvatar = _avatarHash.take(sessionUUID); if (removedAvatar) { handleRemovedAvatar(removedAvatar, removalReason); } - auto surrogateIDs = _surrogates[sessionUUID]; - for (auto id : surrogateIDs) { - _pendingAvatars.remove(id); - auto removedSurrogate = _avatarHash.take(id); - if (removedSurrogate) { - handleRemovedAvatar(removedSurrogate, removalReason); - } - } + } void AvatarHashMap::handleRemovedAvatar(const AvatarSharedPointer& removedAvatar, KillAvatarReason removalReason) { diff --git a/libraries/avatars/src/AvatarHashMap.h b/libraries/avatars/src/AvatarHashMap.h index 41981df693..2d8d7f907f 100644 --- a/libraries/avatars/src/AvatarHashMap.h +++ b/libraries/avatars/src/AvatarHashMap.h @@ -41,6 +41,24 @@ * @hifi-assignment-client */ +class AvatarReplicas { +public: + AvatarReplicas() {}; + void addReplica(const QUuid& parentID, AvatarSharedPointer replica); + std::vector getReplicaIDs(const QUuid& parentID, int count = 0); + void parseDataFromBuffer(const QUuid& parentID, const QByteArray& buffer); + void processAvatarIdentity(const QUuid& parentID, const QByteArray& identityData, bool& identityChanged, bool& displayNameChanged); + void removeReplicas(const QUuid& parentID); + void processTrait(const QUuid& parentID, AvatarTraits::TraitType traitType, QByteArray traitBinaryData); + void processDeletedTraitInstance(const QUuid& parentID, AvatarTraits::TraitType traitType, AvatarTraits::TraitInstanceID instanceID); + void processTraitInstance(const QUuid& parentID, AvatarTraits::TraitType traitType, + AvatarTraits::TraitInstanceID instanceID, QByteArray traitBinaryData); + +private: + std::map> _replicasMap; +}; + + class AvatarHashMap : public QObject, public Dependency { Q_OBJECT SINGLETON_DEPENDENCY @@ -134,7 +152,7 @@ protected slots: */ void processAvatarIdentityPacket(QSharedPointer message, SharedNodePointer sendingNode); - void processAvatarTraits(QUuid sessionUUID, QSharedPointer message, SharedNodePointer sendingNode); + void processBulkAvatarTraitsForID(QUuid sessionUUID, QSharedPointer message, SharedNodePointer sendingNode); void processBulkAvatarTraits(QSharedPointer message, SharedNodePointer sendingNode); /**jsdoc @@ -168,7 +186,8 @@ protected: mutable QReadWriteLock _hashLock; std::unordered_map _processedTraitVersions; - std::map> _surrogates; + AvatarReplicas _replicas; + private: QUuid _lastOwnerSessionUUID; }; From 220dbf586f6e6382d8dc8338c48ec9b42e210ce2 Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 23 Aug 2018 16:46:58 -0700 Subject: [PATCH 084/545] set the phase to 0.0 when it is negative --- libraries/animation/src/AnimBlendLinearMove.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/animation/src/AnimBlendLinearMove.cpp b/libraries/animation/src/AnimBlendLinearMove.cpp index 6313d4cbe9..27352fd546 100644 --- a/libraries/animation/src/AnimBlendLinearMove.cpp +++ b/libraries/animation/src/AnimBlendLinearMove.cpp @@ -155,6 +155,7 @@ void AnimBlendLinearMove::setFrameAndPhase(float dt, float alpha, int prevPoseIn // integrate phase forward in time. _phase += omega * dt; + qCDebug(animation) << "the _phase is " << _phase; // detect loop trigger events if (_phase >= 1.0f) { @@ -172,4 +173,7 @@ void AnimBlendLinearMove::setCurrentFrameInternal(float frame) { assert(clipNode); const float NUM_FRAMES = (clipNode->getEndFrame() - clipNode->getStartFrame()) + 1.0f; _phase = fmodf(frame / NUM_FRAMES, 1.0f); + if (_phase < 0.0f) { + _phase = 0.0f; // 1.0f + _phase; + } } From cee9b909300906f84e156595920e44ab5546dc28 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 23 Aug 2018 16:48:42 -0700 Subject: [PATCH 085/545] working on the LOD behavior --- interface/src/LODManager.cpp | 72 ++++++++++++++++ interface/src/LODManager.h | 11 ++- interface/src/ui/PreferencesDialog.cpp | 9 +- .../render/configSlider/ConfigSlider.qml | 6 +- .../render/configSlider/RichSlider.qml | 82 +++++++++++++++++++ .../utilities/render/configSlider/qmldir | 3 +- scripts/developer/utilities/render/lod.qml | 45 ++++++++-- 7 files changed, 213 insertions(+), 15 deletions(-) create mode 100644 scripts/developer/utilities/render/configSlider/RichSlider.qml diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index 681bdaf884..4f90dee2e5 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -136,6 +136,11 @@ void LODManager::resetLODAdjust() { _decreaseFPSExpiry = _increaseFPSExpiry = usecTimestampNow() + LOD_AUTO_ADJUST_PERIOD; } +void LODManager::setAutomaticLODAdjust(bool value) { + _automaticLODAdjust = value; + emit autoLODChanged(); +} + float LODManager::getLODLevel() const { // simpleLOD is a linearized and normalized number that represents how much LOD is being applied. // It ranges from: @@ -149,7 +154,14 @@ float LODManager::getLODLevel() const { } void LODManager::setLODLevel(float level) { + float simpleLOD = level; + if (!_automaticLODAdjust) { + const float LOG_MIN_LOD_RATIO = logf(ADJUST_LOD_MIN_SIZE_SCALE / ADJUST_LOD_MAX_SIZE_SCALE); + float power = LOG_MIN_LOD_RATIO - (simpleLOD * LOG_MIN_LOD_RATIO); + float sizeScale = expf(power) * ADJUST_LOD_MAX_SIZE_SCALE; + setOctreeSizeScale(sizeScale); + } } const float MIN_DECREASE_FPS = 0.5f; @@ -247,3 +259,63 @@ void LODManager::saveSettings() { hmdLODDecreaseFPS.set(getHMDLODDecreaseFPS()); } +void LODManager::setWorldDetailQuality(float quality) { + + static const float MAX_DESKTOP_FPS = 60; + static const float MAX_HMD_FPS = 90; + static const float MIN_FPS = 10; + static const float LOW = 0.25f; + static const float MEDIUM = 0.5f; + static const float HIGH = 0.75f; + static const float THRASHING_DIFFERENCE = 10; + + bool isLowestValue = quality == LOW; + bool isHMDMode = qApp->isHMDMode(); + + float maxFPS = isHMDMode ? MAX_HMD_FPS : MAX_DESKTOP_FPS; + float desiredFPS = maxFPS - THRASHING_DIFFERENCE; + + if (!isLowestValue) { + float calculatedFPS = (maxFPS - (maxFPS * quality)) - THRASHING_DIFFERENCE; + desiredFPS = calculatedFPS < MIN_FPS ? MIN_FPS : calculatedFPS; + } + + if (isHMDMode) { + setHMDLODDecreaseFPS(desiredFPS); + } + else { + setDesktopLODDecreaseFPS(desiredFPS); + } + + emit worldDetailQualityChanged(); +} + +float LODManager::getWorldDetailQuality() const { + + + static const float MAX_DESKTOP_FPS = 60; + static const float MAX_HMD_FPS = 90; + static const float MIN_FPS = 10; + static const float LOW = 0.25f; + static const float MEDIUM = 0.5f; + static const float HIGH = 0.75f; + + bool inHMD = qApp->isHMDMode(); + + float increaseFPS = 0; + if (inHMD) { + increaseFPS = getHMDLODDecreaseFPS(); + } else { + increaseFPS = getDesktopLODDecreaseFPS(); + } + float maxFPS = inHMD ? MAX_HMD_FPS : MAX_DESKTOP_FPS; + float percentage = increaseFPS / maxFPS; + + if (percentage >= HIGH) { + return LOW; + } + else if (percentage >= LOW) { + return MEDIUM; + } + return HIGH; +} diff --git a/interface/src/LODManager.h b/interface/src/LODManager.h index f0bc1aabf9..de026274ad 100644 --- a/interface/src/LODManager.h +++ b/interface/src/LODManager.h @@ -65,7 +65,9 @@ class LODManager : public QObject, public Dependency { Q_PROPERTY(float lodLevel READ getLODLevel WRITE setLODLevel NOTIFY LODChanged) Q_PROPERTY(float lodDecreaseFPS READ getLODDecreaseFPS) Q_PROPERTY(float lodIncreaseFPS READ getLODIncreaseFPS) - Q_PROPERTY(bool automaticLODAdjust READ getAutomaticLODAdjust WRITE setAutomaticLODAdjust) + Q_PROPERTY(bool automaticLODAdjust READ getAutomaticLODAdjust WRITE setAutomaticLODAdjust NOTIFY autoLODChanged) + + Q_PROPERTY(float worldDetailQuality READ getWorldDetailQuality WRITE setWorldDetailQuality NOTIFY worldDetailQualityChanged) public: @@ -73,7 +75,7 @@ public: * @function LODManager.setAutomaticLODAdjust * @param {boolean} value */ - Q_INVOKABLE void setAutomaticLODAdjust(bool value) { _automaticLODAdjust = value; } + Q_INVOKABLE void setAutomaticLODAdjust(bool value); /**jsdoc * @function LODManager.getAutomaticLODAdjust @@ -179,6 +181,9 @@ public: float getLODLevel() const; void setLODLevel(float level); + void setWorldDetailQuality(float quality); + float getWorldDetailQuality() const; + signals: /**jsdoc @@ -194,6 +199,8 @@ signals: void LODDecreased(); void LODChanged(); + void autoLODChanged(); + void worldDetailQualityChanged(); private: LODManager(); diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index 79ca2063ec..a271e9436c 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -55,7 +55,7 @@ void setupPreferences() { // Graphics quality static const QString GRAPHICS_QUALITY { "Graphics Quality" }; { - static const float MAX_DESKTOP_FPS = 60; + /* static const float MAX_DESKTOP_FPS = 60; static const float MAX_HMD_FPS = 90; static const float MIN_FPS = 10; static const float LOW = 0.25f; @@ -102,6 +102,13 @@ void setupPreferences() { } else { lodManager->setDesktopLODDecreaseFPS(desiredFPS); } + };*/ + auto getter = []()->float { + return DependencyManager::get()->getWorldDetailQuality(); + }; + + auto setter = [](float value) { + DependencyManager::get()->setWorldDetailQuality(value); }; auto wodSlider = new SliderPreference(GRAPHICS_QUALITY, "World Detail", getter, setter); diff --git a/scripts/developer/utilities/render/configSlider/ConfigSlider.qml b/scripts/developer/utilities/render/configSlider/ConfigSlider.qml index 345b29e791..41de77fb09 100644 --- a/scripts/developer/utilities/render/configSlider/ConfigSlider.qml +++ b/scripts/developer/utilities/render/configSlider/ConfigSlider.qml @@ -56,13 +56,13 @@ Item { anchors.verticalCenter: root.verticalCenter } - /* Binding { + Binding { id: bindingControl target: root.config property: root.property value: sliderControl.value when: false - }*/ + } HifiControls.Slider { id: sliderControl @@ -73,7 +73,7 @@ Item { anchors.top: root.top anchors.topMargin: 0 - // onValueChanged: { root.valueChanged(value) } + onValueChanged: { root.valueChanged(value) } } HifiControls.Label { diff --git a/scripts/developer/utilities/render/configSlider/RichSlider.qml b/scripts/developer/utilities/render/configSlider/RichSlider.qml new file mode 100644 index 0000000000..c44727cfa4 --- /dev/null +++ b/scripts/developer/utilities/render/configSlider/RichSlider.qml @@ -0,0 +1,82 @@ +// +// RichSlider.qml +// +// Created by Zach Pomerantz on 2/8/2016 +// Copyright 2016 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.7 +import QtQuick.Controls 1.4 as Original +import QtQuick.Controls.Styles 1.4 + +import "qrc:///qml/styles-uit" +import "qrc:///qml/controls-uit" as HifiControls + + +Item { + HifiConstants { id: hifi } + id: root + + anchors.left: parent.left + anchors.right: parent.right + height: 24 + + function defaultGet() { return 0 } + function defaultSet(value) { } + + property var labelAreaWidthScale: 0.5 + + property bool integral: false + property var valueVarGetter: defaultGet + property var valueVarSetter: defaultSet + // property string property + property alias valueVar : sliderControl.value + // property alias valueSetter : sliderControl.value + property alias min: sliderControl.minimumValue + property alias max: sliderControl.maximumValue + + property alias label: labelControl.text + property bool showLabel: true + + property bool showValue: true + + + + signal valueChanged(real value) + + Component.onCompleted: { + } + + HifiControls.Label { + id: labelControl + text: root.label + enabled: root.showLabel + anchors.left: root.left + width: root.width * root.labelAreaWidthScale + anchors.verticalCenter: root.verticalCenter + } + + HifiControls.Slider { + id: sliderControl + stepSize: root.integral ? 1.0 : 0.0 + anchors.left: labelControl.right + anchors.right: root.right + anchors.rightMargin: 0 + anchors.top: root.top + anchors.topMargin: 0 + onValueChanged: { root.valueVarSetter(value) } + } + + HifiControls.Label { + id: labelValue + enabled: root.showValue + text: sliderControl.value.toFixed(root.integral ? 0 : 2) + anchors.right: labelControl.right + anchors.rightMargin: 5 + anchors.verticalCenter: root.verticalCenter + } + +} diff --git a/scripts/developer/utilities/render/configSlider/qmldir b/scripts/developer/utilities/render/configSlider/qmldir index 6680ec9638..479f786b22 100644 --- a/scripts/developer/utilities/render/configSlider/qmldir +++ b/scripts/developer/utilities/render/configSlider/qmldir @@ -1 +1,2 @@ -ConfigSlider 1.0 ConfigSlider.qml \ No newline at end of file +ConfigSlider 1.0 ConfigSlider.qml +RichSlider 1.0 RichSlider.qml \ No newline at end of file diff --git a/scripts/developer/utilities/render/lod.qml b/scripts/developer/utilities/render/lod.qml index 36a19c10f2..25a0d20db6 100644 --- a/scripts/developer/utilities/render/lod.qml +++ b/scripts/developer/utilities/render/lod.qml @@ -44,21 +44,50 @@ Item { } HifiControls.CheckBox { boxSize: 20 - text: "Manual LOD" - checked: LODManager.getAutomaticLODAdjust() - onCheckedChanged: { LODManager.setAutomaticLODAdjust(checked) } + text: "Auto LOD" + checked: LODManager.automaticLODAdjust + onCheckedChanged: { LODManager.automaticLODAdjust = (checked) } } - ConfigSlider { +property var lodObject: LODManager + + RichSlider { showLabel: true - config: LODManager - property: "lodLevel" - max: 13 - min: 0 + label: "lodLevel" + valueVar: LODManager["lodLevel"] + valueVarSetter: (function (v) { LODManager["lodLevel"] = v }) + max: 1.0 + min: 0.0 integral: false anchors.left: parent.left anchors.right: parent.right } + RichSlider { + showLabel: true + // config: lodObject + // property: "worldDetailQuality" + // valueVar: LODManager["worldDetailQuality"] + label: "World Quality" + valueVar: LODManager["worldDetailQuality"] + // valueVarGetter: { return LODManager["worldDetailQuality"] } + valueVarSetter: (function (v) { LODManager["worldDetailQuality"] = v }) + max: 0.75 + min: 0.25 + integral: false + + anchors.left: parent.left + anchors.right: parent.right + } + /* HifiControls.Slider { + id: sliderControl + stepSize: 0.0 + minimumValue: 0.0 + maximumValue: 1.2 + anchors.left: parent.left + anchors.right: parent.right + value: LODManager["lodLevel"] + onValueChanged: { LODManager["lodLevel"] = value } + }*/ } From 1263db568823c5577bd7fa1cddf897acd7711c5a Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 23 Aug 2018 16:08:16 -0700 Subject: [PATCH 086/545] force NL reset if the domain changes session ID or local ID --- libraries/networking/src/NodeList.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index dd351ef940..4e8cbbf9db 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -273,6 +273,7 @@ void NodeList::reset(bool skipDomainHandlerReset) { // refresh the owner UUID to the NULL UUID setSessionUUID(QUuid()); + setSessionLocalID(Node::NULL_LOCAL_ID); // if we setup the DTLS socket, also disconnect from the DTLS socket readyRead() so it can handle handshaking if (_dtlsSocket) { @@ -647,6 +648,17 @@ void NodeList::processDomainServerList(QSharedPointer message) Node::LocalID newLocalID; packetStream >> newUUID; packetStream >> newLocalID; + + // when connected, if the session ID or local ID were not null and changed, we should reset + auto currentLocalID = getSessionLocalID(); + auto currentSessionID = getSessionUUID(); + if (_domainHandler.isConnected() && + ((currentLocalID != Node::NULL_LOCAL_ID && newLocalID != currentLocalID) || + (!currentSessionID.isNull() && newUUID != currentSessionID))) { + qCDebug(networking) << "Local ID or Session ID changed while connected to domain - forcing NodeList reset"; + reset(true); + } + setSessionLocalID(newLocalID); setSessionUUID(newUUID); From 0cc302f68c9812325f19a55158503b5339ccd82b Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 23 Aug 2018 17:28:38 -0700 Subject: [PATCH 087/545] set phase to 0.0 --- libraries/animation/src/AnimBlendLinearMove.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/libraries/animation/src/AnimBlendLinearMove.cpp b/libraries/animation/src/AnimBlendLinearMove.cpp index 27352fd546..d648b9966f 100644 --- a/libraries/animation/src/AnimBlendLinearMove.cpp +++ b/libraries/animation/src/AnimBlendLinearMove.cpp @@ -139,6 +139,8 @@ void AnimBlendLinearMove::setFrameAndPhase(float dt, float alpha, int prevPoseIn auto nextClipNode = std::dynamic_pointer_cast(_children[nextPoseIndex]); assert(nextClipNode); + + float v0 = _characteristicSpeeds[prevPoseIndex]; float n0 = (prevClipNode->getEndFrame() - prevClipNode->getStartFrame()) + 1.0f; float v1 = _characteristicSpeeds[nextPoseIndex]; @@ -153,9 +155,17 @@ void AnimBlendLinearMove::setFrameAndPhase(float dt, float alpha, int prevPoseIn float f1 = nextClipNode->getStartFrame() + _phase * n1; nextClipNode->setCurrentFrame(f1); + + // integrate phase forward in time. _phase += omega * dt; - qCDebug(animation) << "the _phase is " << _phase; + + qCDebug(animation) << "the _phase is " << _phase << " and omega " << omega << _desiredSpeed; + + if (_phase < 0.0f) { + _phase = 0.0f; // 1.0f + _phase; + } + // detect loop trigger events if (_phase >= 1.0f) { @@ -173,7 +183,4 @@ void AnimBlendLinearMove::setCurrentFrameInternal(float frame) { assert(clipNode); const float NUM_FRAMES = (clipNode->getEndFrame() - clipNode->getStartFrame()) + 1.0f; _phase = fmodf(frame / NUM_FRAMES, 1.0f); - if (_phase < 0.0f) { - _phase = 0.0f; // 1.0f + _phase; - } } From 884be2f99d4a7ea417260902880e412264ad2d5a Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 23 Aug 2018 17:30:03 -0700 Subject: [PATCH 088/545] removed comment and whitespace --- libraries/animation/src/AnimBlendLinearMove.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/libraries/animation/src/AnimBlendLinearMove.cpp b/libraries/animation/src/AnimBlendLinearMove.cpp index d648b9966f..8879f3d9d4 100644 --- a/libraries/animation/src/AnimBlendLinearMove.cpp +++ b/libraries/animation/src/AnimBlendLinearMove.cpp @@ -155,18 +155,13 @@ void AnimBlendLinearMove::setFrameAndPhase(float dt, float alpha, int prevPoseIn float f1 = nextClipNode->getStartFrame() + _phase * n1; nextClipNode->setCurrentFrame(f1); - - // integrate phase forward in time. _phase += omega * dt; - - qCDebug(animation) << "the _phase is " << _phase << " and omega " << omega << _desiredSpeed; if (_phase < 0.0f) { - _phase = 0.0f; // 1.0f + _phase; + _phase = 0.0f; } - // detect loop trigger events if (_phase >= 1.0f) { triggersOut.setTrigger(_id + "Loop"); From 57fd824005681efef2b798e4ceb40bc20a67f0c7 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 23 Aug 2018 17:30:23 -0700 Subject: [PATCH 089/545] working on the LOD behavior --- .../render/configSlider/RichSlider.qml | 8 +-- scripts/developer/utilities/render/lod.qml | 59 ++++++++----------- 2 files changed, 27 insertions(+), 40 deletions(-) diff --git a/scripts/developer/utilities/render/configSlider/RichSlider.qml b/scripts/developer/utilities/render/configSlider/RichSlider.qml index c44727cfa4..1613cac1b4 100644 --- a/scripts/developer/utilities/render/configSlider/RichSlider.qml +++ b/scripts/developer/utilities/render/configSlider/RichSlider.qml @@ -28,13 +28,11 @@ Item { function defaultSet(value) { } property var labelAreaWidthScale: 0.5 - property bool integral: false - property var valueVarGetter: defaultGet + property var valueVarSetter: defaultSet - // property string property - property alias valueVar : sliderControl.value - // property alias valueSetter : sliderControl.value + property alias valueVar : sliderControl.value + property alias min: sliderControl.minimumValue property alias max: sliderControl.maximumValue diff --git a/scripts/developer/utilities/render/lod.qml b/scripts/developer/utilities/render/lod.qml index 25a0d20db6..452d5c7930 100644 --- a/scripts/developer/utilities/render/lod.qml +++ b/scripts/developer/utilities/render/lod.qml @@ -42,17 +42,33 @@ Item { checked: Render.getConfig("RenderMainView.DrawSceneOctree").enabled onCheckedChanged: { Render.getConfig("RenderMainView.DrawSceneOctree").enabled = checked } } - HifiControls.CheckBox { - boxSize: 20 - text: "Auto LOD" - checked: LODManager.automaticLODAdjust - onCheckedChanged: { LODManager.automaticLODAdjust = (checked) } - } -property var lodObject: LODManager RichSlider { showLabel: true - label: "lodLevel" + showValue: false + label: "World Quality" + valueVar: LODManager["worldDetailQuality"] + valueVarSetter: (function (v) { LODManager["worldDetailQuality"] = v }) + max: 0.75 + min: 0.25 + integral: false + + anchors.left: autoLOD.left + anchors.right: parent.right + } + + HifiControls.CheckBox { + id: autoLOD + boxSize: 20 + text: "Auto LOD" + checked: LODManager.automaticLODAdjust + onCheckedChanged: { LODManager.automaticLODAdjust = (checked) } + } + + RichSlider { + visible: !LODManager.automaticLODAdjust + showLabel: true + label: "LOD Level" valueVar: LODManager["lodLevel"] valueVarSetter: (function (v) { LODManager["lodLevel"] = v }) max: 1.0 @@ -62,33 +78,6 @@ property var lodObject: LODManager anchors.left: parent.left anchors.right: parent.right } - RichSlider { - showLabel: true - // config: lodObject - // property: "worldDetailQuality" - // valueVar: LODManager["worldDetailQuality"] - label: "World Quality" - valueVar: LODManager["worldDetailQuality"] - // valueVarGetter: { return LODManager["worldDetailQuality"] } - valueVarSetter: (function (v) { LODManager["worldDetailQuality"] = v }) - max: 0.75 - min: 0.25 - integral: false - - anchors.left: parent.left - anchors.right: parent.right - } - /* HifiControls.Slider { - id: sliderControl - stepSize: 0.0 - minimumValue: 0.0 - maximumValue: 1.2 - anchors.left: parent.left - anchors.right: parent.right - value: LODManager["lodLevel"] - onValueChanged: { LODManager["lodLevel"] = value } - }*/ - } Column { From 671bf32d5813ef84837e7d22fd83933d4f9cba5e Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 23 Aug 2018 17:36:35 -0700 Subject: [PATCH 090/545] removed whitespace --- libraries/animation/src/AnimBlendLinearMove.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/animation/src/AnimBlendLinearMove.cpp b/libraries/animation/src/AnimBlendLinearMove.cpp index 8879f3d9d4..42098eb072 100644 --- a/libraries/animation/src/AnimBlendLinearMove.cpp +++ b/libraries/animation/src/AnimBlendLinearMove.cpp @@ -139,8 +139,6 @@ void AnimBlendLinearMove::setFrameAndPhase(float dt, float alpha, int prevPoseIn auto nextClipNode = std::dynamic_pointer_cast(_children[nextPoseIndex]); assert(nextClipNode); - - float v0 = _characteristicSpeeds[prevPoseIndex]; float n0 = (prevClipNode->getEndFrame() - prevClipNode->getStartFrame()) + 1.0f; float v1 = _characteristicSpeeds[nextPoseIndex]; From b5b71676448c1805321831e6c363076d1a4c0f94 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 23 Aug 2018 17:47:25 -0700 Subject: [PATCH 091/545] add to stats --- interface/resources/qml/Stats.qml | 16 ++++ interface/src/ui/Stats.cpp | 17 ++++- interface/src/ui/Stats.h | 75 ++++++++++++++++++- .../src/RenderablePolyVoxEntityItem.cpp | 1 - libraries/entities/src/EntityTreeElement.cpp | 6 -- libraries/pointers/src/PickCacheOptimizer.h | 10 ++- libraries/pointers/src/PickManager.cpp | 14 ++-- libraries/pointers/src/PickManager.h | 6 ++ libraries/render-utils/src/Model.cpp | 12 +-- 9 files changed, 134 insertions(+), 23 deletions(-) diff --git a/interface/resources/qml/Stats.qml b/interface/resources/qml/Stats.qml index 2e6e909312..8b277d4c20 100644 --- a/interface/resources/qml/Stats.qml +++ b/interface/resources/qml/Stats.qml @@ -116,6 +116,22 @@ Item { visible: root.expanded text: "Avatars NOT Updated: " + root.notUpdatedAvatarCount } + StatText { + visible: root.expanded + text: "Total picks:\n " + + root.stylusPicksCount + " styluses\n " + + root.rayPicksCount + " rays\n " + + root.parabolaPicksCount + " parabolas\n " + + root.collisionPicksCount + " colliders" + } + StatText { + visible: root.expanded + text: "Intersection calls: Entities/Overlays/Avatars/HUD\n " + + root.stylusPicksUpdated.x + "/" + root.stylusPicksUpdated.y + "/" + root.stylusPicksUpdated.z + "/" + root.stylusPicksUpdated.w + "\n " + + root.rayPicksUpdated.x + "/" + root.rayPicksUpdated.y + "/" + root.rayPicksUpdated.z + "/" + root.rayPicksUpdated.w + "\n " + + root.parabolaPicksUpdated.x + "/" + root.parabolaPicksUpdated.y + "/" + root.parabolaPicksUpdated.z + "/" + root.parabolaPicksUpdated.w + "\n " + + root.collisionPicksUpdated.x + "/" + root.collisionPicksUpdated.y + "/" + root.collisionPicksUpdated.z + "/" + root.collisionPicksUpdated.w + } } } diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index ce1cd51de1..16e2bb955f 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -146,6 +147,20 @@ void Stats::updateStats(bool force) { } STAT_UPDATE(gameLoopRate, (int)qApp->getGameLoopRate()); + auto pickManager = DependencyManager::get(); + if (pickManager && (_expanded || force)) { + std::vector totalPicks = pickManager->getTotalPickCounts(); + STAT_UPDATE(stylusPicksCount, totalPicks[PickQuery::Stylus]); + STAT_UPDATE(rayPicksCount, totalPicks[PickQuery::Ray]); + STAT_UPDATE(parabolaPicksCount, totalPicks[PickQuery::Parabola]); + STAT_UPDATE(collisionPicksCount, totalPicks[PickQuery::Collision]); + std::vector updatedPicks = pickManager->getUpdatedPickCounts(); + STAT_UPDATE(stylusPicksUpdated, updatedPicks[PickQuery::Stylus]); + STAT_UPDATE(rayPicksUpdated, updatedPicks[PickQuery::Ray]); + STAT_UPDATE(parabolaPicksUpdated, updatedPicks[PickQuery::Parabola]); + STAT_UPDATE(collisionPicksUpdated, updatedPicks[PickQuery::Collision]); + } + auto bandwidthRecorder = DependencyManager::get(); STAT_UPDATE(packetInCount, (int)bandwidthRecorder->getCachedTotalAverageInputPacketsPerSecond()); STAT_UPDATE(packetOutCount, (int)bandwidthRecorder->getCachedTotalAverageOutputPacketsPerSecond()); @@ -285,7 +300,7 @@ void Stats::updateStats(bool force) { // downloads << (int)(resource->getProgress() * 100.0f) << "% "; //} //downloads << "(" << << " pending)"; - } // expanded avatar column + } // Fourth column, octree stats int serverCount = 0; diff --git a/interface/src/ui/Stats.h b/interface/src/ui/Stats.h index cf624b54c3..7845a540de 100644 --- a/interface/src/ui/Stats.h +++ b/interface/src/ui/Stats.h @@ -22,7 +22,6 @@ public: \ private: \ type _##name{ initialValue }; - /**jsdoc * @namespace Stats * @@ -168,6 +167,15 @@ private: \ * @property {number} implicitHeight * * @property {object} layer - Read-only. + + * @property {number} stylusPicksCount - Read-only. + * @property {number} rayPicksCount - Read-only. + * @property {number} parabolaPicksCount - Read-only. + * @property {number} collisionPicksCount - Read-only. + * @property {Vec4} stylusPicksUpdated - Read-only. + * @property {Vec4} rayPicksUpdated - Read-only. + * @property {Vec4} parabolaPicksUpdated - Read-only. + * @property {Vec4} collisionPicksUpdated - Read-only. */ // Properties from x onwards are QQuickItem properties. @@ -285,6 +293,15 @@ class Stats : public QQuickItem { STATS_PROPERTY(float, avatarSimulationTime, 0) Q_PROPERTY(QStringList animStackNames READ animStackNames NOTIFY animStackNamesChanged) + STATS_PROPERTY(int, stylusPicksCount, 0) + STATS_PROPERTY(int, rayPicksCount, 0) + STATS_PROPERTY(int, parabolaPicksCount, 0) + STATS_PROPERTY(int, collisionPicksCount, 0) + STATS_PROPERTY(QVector4D, stylusPicksUpdated, QVector4D(0, 0, 0, 0)) + STATS_PROPERTY(QVector4D, rayPicksUpdated, QVector4D(0, 0, 0, 0)) + STATS_PROPERTY(QVector4D, parabolaPicksUpdated, QVector4D(0, 0, 0, 0)) + STATS_PROPERTY(QVector4D, collisionPicksUpdated, QVector4D(0, 0, 0, 0)) + public: static Stats* getInstance(); @@ -1245,6 +1262,62 @@ signals: * @function Stats.update */ + /**jsdoc + * Triggered when the value of the stylusPicksCount property changes. + * @function Stats.stylusPicksCountChanged + * @returns {Signal} + */ + void stylusPicksCountChanged(); + + /**jsdoc + * Triggered when the value of the rayPicksCount property changes. + * @function Stats.rayPicksCountChanged + * @returns {Signal} + */ + void rayPicksCountChanged(); + + /**jsdoc + * Triggered when the value of the parabolaPicksCount property changes. + * @function Stats.parabolaPicksCountChanged + * @returns {Signal} + */ + void parabolaPicksCountChanged(); + + /**jsdoc + * Triggered when the value of the collisionPicksCount property changes. + * @function Stats.collisionPicksCountChanged + * @returns {Signal} + */ + void collisionPicksCountChanged(); + + /**jsdoc + * Triggered when the value of the stylusPicksUpdated property changes. + * @function Stats.stylusPicksUpdatedChanged + * @returns {Signal} + */ + void stylusPicksUpdatedChanged(); + + /**jsdoc + * Triggered when the value of the rayPicksUpdated property changes. + * @function Stats.rayPicksUpdatedChanged + * @returns {Signal} + */ + void rayPicksUpdatedChanged(); + + /**jsdoc + * Triggered when the value of the parabolaPicksUpdated property changes. + * @function Stats.parabolaPicksUpdatedChanged + * @returns {Signal} + */ + void parabolaPicksUpdatedChanged(); + + /**jsdoc + * Triggered when the value of the collisionPicksUpdated property changes. + * @function Stats.collisionPicksUpdatedChanged + * @returns {Signal} + */ + void collisionPicksUpdatedChanged(); + private: int _recentMaxPackets{ 0 } ; // recent max incoming voxel packets to process bool _resetRecentMaxPacketsSoon{ true }; diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index 63f27dd170..af8d4fac86 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -571,7 +571,6 @@ bool RenderablePolyVoxEntityItem::findDetailedRayIntersection(const glm::vec3& o } glm::mat4 wtvMatrix = worldToVoxelMatrix(); - glm::mat4 vtwMatrix = voxelToWorldMatrix(); glm::vec3 normDirection = glm::normalize(direction); // the PolyVox ray intersection code requires a near and far point. diff --git a/libraries/entities/src/EntityTreeElement.cpp b/libraries/entities/src/EntityTreeElement.cpp index e8e11c0ee1..b7288755a6 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -145,7 +145,6 @@ EntityItemID EntityTreeElement::findRayIntersection(const glm::vec3& origin, con bool visibleOnly, bool collidableOnly, QVariantMap& extraInfo, bool precisionPicking) { EntityItemID result; - float distanceToElementCube = FLT_MAX; BoxFace localFace; glm::vec3 localSurfaceNormal; @@ -153,8 +152,6 @@ EntityItemID EntityTreeElement::findRayIntersection(const glm::vec3& origin, con return result; } - // if the distance to the element cube is not less than the current best distance, then it's not possible - // for any details inside the cube to be closer so we don't need to consider them. QVariantMap localExtraInfo; float distanceToElementDetails = distance; EntityItemID entityID = findDetailedRayIntersection(origin, direction, element, distanceToElementDetails, @@ -285,7 +282,6 @@ EntityItemID EntityTreeElement::findParabolaIntersection(const glm::vec3& origin QVariantMap& extraInfo, bool precisionPicking) { EntityItemID result; - float distanceToElementCube = std::numeric_limits::max(); BoxFace localFace; glm::vec3 localSurfaceNormal; @@ -293,8 +289,6 @@ EntityItemID EntityTreeElement::findParabolaIntersection(const glm::vec3& origin return result; } - // if the distance to the element cube is not less than the current best distance, then it's not possible - // for any details inside the cube to be closer so we don't need to consider them. QVariantMap localExtraInfo; float distanceToElementDetails = parabolicDistance; // We can precompute the world-space parabola normal and reuse it for the parabola plane intersects AABox sphere check diff --git a/libraries/pointers/src/PickCacheOptimizer.h b/libraries/pointers/src/PickCacheOptimizer.h index 49a039935c..7a52cfc410 100644 --- a/libraries/pointers/src/PickCacheOptimizer.h +++ b/libraries/pointers/src/PickCacheOptimizer.h @@ -37,7 +37,7 @@ template class PickCacheOptimizer { public: - void update(std::unordered_map>& picks, uint32_t& nextToUpdate, uint64_t expiry, bool shouldPickHUD); + QVector4D update(std::unordered_map>& picks, uint32_t& nextToUpdate, uint64_t expiry, bool shouldPickHUD); protected: typedef std::unordered_map> PickCache; @@ -67,8 +67,9 @@ void PickCacheOptimizer::cacheResult(const bool intersects, const PickResultP } template -void PickCacheOptimizer::update(std::unordered_map>& picks, +QVector4D PickCacheOptimizer::update(std::unordered_map>& picks, uint32_t& nextToUpdate, uint64_t expiry, bool shouldPickHUD) { + QVector4D numIntersectionsComputed; PickCache results; const uint32_t INVALID_PICK_ID = 0; auto itr = picks.begin(); @@ -91,6 +92,7 @@ void PickCacheOptimizer::update(std::unordered_mapgetFilter().getEntityFlags(), pick->getIncludeItems(), pick->getIgnoreItems() }; if (!checkAndCompareCachedResults(mathematicalPick, results, res, entityKey)) { PickResultPointer entityRes = pick->getEntityIntersection(mathematicalPick); + numIntersectionsComputed[0]++; if (entityRes) { cacheResult(entityRes->doesIntersect(), entityRes, entityKey, res, mathematicalPick, results, pick); } @@ -101,6 +103,7 @@ void PickCacheOptimizer::update(std::unordered_mapgetFilter().getOverlayFlags(), pick->getIncludeItems(), pick->getIgnoreItems() }; if (!checkAndCompareCachedResults(mathematicalPick, results, res, overlayKey)) { PickResultPointer overlayRes = pick->getOverlayIntersection(mathematicalPick); + numIntersectionsComputed[1]++; if (overlayRes) { cacheResult(overlayRes->doesIntersect(), overlayRes, overlayKey, res, mathematicalPick, results, pick); } @@ -111,6 +114,7 @@ void PickCacheOptimizer::update(std::unordered_mapgetFilter().getAvatarFlags(), pick->getIncludeItems(), pick->getIgnoreItems() }; if (!checkAndCompareCachedResults(mathematicalPick, results, res, avatarKey)) { PickResultPointer avatarRes = pick->getAvatarIntersection(mathematicalPick); + numIntersectionsComputed[2]++; if (avatarRes) { cacheResult(avatarRes->doesIntersect(), avatarRes, avatarKey, res, mathematicalPick, results, pick); } @@ -122,6 +126,7 @@ void PickCacheOptimizer::update(std::unordered_mapgetFilter().getHUDFlags(), QVector(), QVector() }; if (!checkAndCompareCachedResults(mathematicalPick, results, res, hudKey)) { PickResultPointer hudRes = pick->getHUDIntersection(mathematicalPick); + numIntersectionsComputed[3]++; if (hudRes) { cacheResult(true, hudRes, hudKey, res, mathematicalPick, results, pick); } @@ -145,6 +150,7 @@ void PickCacheOptimizer::update(std::unordered_mapsecond].erase(uid); _typeMap.erase(uid); + _totalPickCounts[type->second]--; } }); } @@ -96,12 +98,12 @@ void PickManager::update() { }); bool shouldPickHUD = _shouldPickHUDOperator(); - // we pass the same expiry to both updates, but the stylus updates are relatively cheap - // and the rayPicks updae will ALWAYS update at least one ray even when there is no budget - _stylusPickCacheOptimizer.update(cachedPicks[PickQuery::Stylus], _nextPickToUpdate[PickQuery::Stylus], expiry, false); - _rayPickCacheOptimizer.update(cachedPicks[PickQuery::Ray], _nextPickToUpdate[PickQuery::Ray], expiry, shouldPickHUD); - _parabolaPickCacheOptimizer.update(cachedPicks[PickQuery::Parabola], _nextPickToUpdate[PickQuery::Parabola], expiry, shouldPickHUD); - _collisionPickCacheOptimizer.update(cachedPicks[PickQuery::Collision], _nextPickToUpdate[PickQuery::Collision], expiry, false); + // FIXME: give each type its own expiry + // Each type will update at least one pick, regardless of the expiry + _updatedPickCounts[PickQuery::Stylus] = _stylusPickCacheOptimizer.update(cachedPicks[PickQuery::Stylus], _nextPickToUpdate[PickQuery::Stylus], expiry, false); + _updatedPickCounts[PickQuery::Ray] = _rayPickCacheOptimizer.update(cachedPicks[PickQuery::Ray], _nextPickToUpdate[PickQuery::Ray], expiry, shouldPickHUD); + _updatedPickCounts[PickQuery::Parabola] = _parabolaPickCacheOptimizer.update(cachedPicks[PickQuery::Parabola], _nextPickToUpdate[PickQuery::Parabola], expiry, shouldPickHUD); + _updatedPickCounts[PickQuery::Collision] = _collisionPickCacheOptimizer.update(cachedPicks[PickQuery::Collision], _nextPickToUpdate[PickQuery::Collision], expiry, false); } bool PickManager::isLeftHand(unsigned int uid) { diff --git a/libraries/pointers/src/PickManager.h b/libraries/pointers/src/PickManager.h index 595c43e71d..e8d32771e0 100644 --- a/libraries/pointers/src/PickManager.h +++ b/libraries/pointers/src/PickManager.h @@ -58,10 +58,16 @@ public: bool getForceCoarsePicking() { return _forceCoarsePicking; } + const std::vector& getUpdatedPickCounts() { return _updatedPickCounts; } + const std::vector& getTotalPickCounts() { return _totalPickCounts; } + public slots: void setForceCoarsePicking(bool forceCoarsePicking) { _forceCoarsePicking = forceCoarsePicking; } protected: + std::vector _updatedPickCounts { PickQuery::NUM_PICK_TYPES }; + std::vector _totalPickCounts { 0, 0, 0, 0 }; + bool _forceCoarsePicking { false }; std::function _shouldPickHUDOperator; std::function _calculatePos2DFromHUDOperator; diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 22bc6b6ca7..ae3ee6e9a2 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -385,9 +385,9 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g Triangle bestWorldTriangle; glm::vec3 bestWorldIntersectionPoint; glm::vec3 bestMeshIntersectionPoint; - int bestPartIndex; - int bestShapeID; - int bestSubMeshIndex; + int bestPartIndex = 0; + int bestShapeID = 0; + int bestSubMeshIndex = 0; const FBXGeometry& geometry = getFBXGeometry(); if (!_triangleSetsValid) { @@ -527,9 +527,9 @@ bool Model::findParabolaIntersectionAgainstSubMeshes(const glm::vec3& origin, co Triangle bestWorldTriangle; glm::vec3 bestWorldIntersectionPoint; glm::vec3 bestMeshIntersectionPoint; - int bestPartIndex; - int bestShapeID; - int bestSubMeshIndex; + int bestPartIndex = 0; + int bestShapeID = 0; + int bestSubMeshIndex = 0; const FBXGeometry& geometry = getFBXGeometry(); if (!_triangleSetsValid) { From 0e0561bb24bfbf93f62b71ef18276e15d8c415fa Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 23 Aug 2018 17:59:18 -0700 Subject: [PATCH 092/545] latest rotate code --- interface/src/avatar/MyAvatar.cpp | 20 +++++++++++++++----- scripts/developer/rotateApp.js | 2 +- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 6211e6f0d8..8d9c503e5e 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -462,7 +462,7 @@ void MyAvatar::update(float deltaTime) { setCurrentStandingHeight(computeStandingHeightMode(getControllerPoseInAvatarFrame(controller::Action::HEAD))); setAverageHeadRotation(computeAverageHeadRotation(getControllerPoseInAvatarFrame(controller::Action::HEAD))); - + computeHandAzimuth(); #ifdef DEBUG_DRAW_HMD_MOVING_AVERAGE @@ -473,6 +473,14 @@ void MyAvatar::update(float deltaTime) { glm::vec3 worldFacing = transformVectorFast(getSensorToWorldMatrix(), glm::vec3(_headControllerFacing.x, 0.0f, _headControllerFacing.y)); DebugDraw::getInstance().drawRay(worldHeadPos, worldHeadPos + worldFacing, glm::vec4(0.0f, 1.0f, 0.0f, 1.0f)); DebugDraw::getInstance().drawRay(worldHeadPos, worldHeadPos + worldFacingAverage, glm::vec4(0.0f, 0.0f, 1.0f, 1.0f)); + + // draw hand azimuth vector + + glm::vec3 worldRHandAzimuth = transformPoint(getTransform().getMatrix(), getControllerPoseInAvatarFrame(controller::Action::RIGHT_HAND).getTranslation()); + glm::vec3 worldLHandAzimuth = transformPoint(getTransform().getMatrix(), getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND).getTranslation()); + qCDebug(interfaceapp) << "the right hand in avatar space" << worldRHandAzimuth << " " << getWorldPosition(); + DebugDraw::getInstance().drawRay(getWorldPosition(), worldRHandAzimuth, glm::vec4(0.0f, 1.0f, 0.0f, 1.0f)); + DebugDraw::getInstance().drawRay(getWorldPosition(), worldLHandAzimuth, glm::vec4(0.0f, 1.0f, 0.0f, 1.0f)); } #endif @@ -802,11 +810,13 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { } void MyAvatar::computeHandAzimuth() { - controller::Pose leftHandPoseAvatarSpace = getLeftHandPose(); - controller::Pose rightHandPoseAvatarSpace = getRightHandPose(); + auto leftHandPoseAvatarSpace = getLeftHandPose(); + auto rightHandPoseAvatarSpace = getRightHandPose(); glm::vec3 localLookat(0.0f, 0.0f, 1.0f); - glm::vec3 rightHandRigSpace = rightHandPoseAvatarSpace.rotation * localLookat; - glm::vec3 lefttHandRigSpace = leftHandPoseAvatarSpace.rotation * localLookat; + glm::vec3 rightHandRigSpace = rightHandPoseAvatarSpace.translation;// transformVectorFast(getTransform().getMatrix(), rightHandPoseAvatarSpace.translation); + glm::vec3 leftHandRigSpace = leftHandPoseAvatarSpace.translation;// transformVectorFast(getTransform().getMatrix(), leftHandPoseAvatarSpace.translation); + + //qCDebug(interfaceapp) << "the right hand in avatar space" << rightHandRigSpace; _hipToHandController = glm::vec2(rightHandRigSpace.x, rightHandRigSpace.z); diff --git a/scripts/developer/rotateApp.js b/scripts/developer/rotateApp.js index 60d78d66d9..e4080c9bb0 100644 --- a/scripts/developer/rotateApp.js +++ b/scripts/developer/rotateApp.js @@ -320,7 +320,7 @@ function computeHandAzimuths(timeElapsed) { // put a hard max on this easing function. var rotateAngle = ((Math.cos((leftRightMidpoint / 180.0) * Math.PI) + 2.0)/3.0) * leftRightMidpoint; - print("rotate angle " + rotateAngle); + //print("rotate angle " + rotateAngle); return Quat.fromVec3Degrees({ x: 0, y: rotateAngle, z: 0 }); From 1fd0d7da94c3cca2f4dc367cc41f8e84eed1f072 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Thu, 23 Aug 2018 18:03:27 -0700 Subject: [PATCH 093/545] Create API call --- libraries/avatars/src/AvatarHashMap.cpp | 24 +++++++++++++++++------- libraries/avatars/src/AvatarHashMap.h | 12 ++++++++++-- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index 800825f574..6949efc19c 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -32,15 +32,15 @@ void AvatarReplicas::addReplica(const QUuid& parentID, AvatarSharedPointer repli replicas.push_back(replica); } -std::vector AvatarReplicas::getReplicaIDs(const QUuid& parentID, int count) { +std::vector AvatarReplicas::getReplicaIDs(const QUuid& parentID) { std::vector ids; if (_replicasMap.find(parentID) != _replicasMap.end()) { auto &replicas = _replicasMap[parentID]; for (int i = 0; i < replicas.size(); i++) { ids.push_back(replicas[i]->getID()); } - } else if (count > 0) { - for (int i = 0; i < count; i++) { + } else if (_replicaCount > 0) { + for (int i = 0; i < _replicaCount; i++) { ids.push_back(QUuid::createUuid()); } } @@ -139,6 +139,19 @@ bool AvatarHashMap::isAvatarInRange(const glm::vec3& position, const float range return false; } +void AvatarHashMap::setReplicaCount(int count) { + _replicas.setReplicaCount(count); + auto avatars = getAvatarIdentifiers(); + for (int i = 0; i < avatars.size(); i++) { + KillAvatarReason reason = KillAvatarReason::NoReason; + removeAvatar(avatars[i], reason); + auto replicaIDs = _replicas.getReplicaIDs(avatars[i]); + for (auto id : replicaIDs) { + removeAvatar(id, reason); + } + } +} + int AvatarHashMap::numberOfAvatarsInRange(const glm::vec3& position, float rangeMeters) { auto hashCopy = getHashCopy(); auto rangeMeters2 = rangeMeters * rangeMeters; @@ -210,9 +223,6 @@ AvatarSharedPointer AvatarHashMap::parseAvatarData(QSharedPointer(); - - const int REPLICAS_COUNT = 8; - bool isNewAvatar; if (sessionUUID != _lastOwnerSessionUUID && (!nodeList->isIgnoringNode(sessionUUID) || nodeList->getRequestsDomainListData())) { auto avatar = newOrExistingAvatar(sessionUUID, sendingNode, isNewAvatar); @@ -220,7 +230,7 @@ AvatarSharedPointer AvatarHashMap::parseAvatarData(QSharedPointer getReplicaIDs(const QUuid& parentID, int count = 0); + std::vector getReplicaIDs(const QUuid& parentID); void parseDataFromBuffer(const QUuid& parentID, const QByteArray& buffer); void processAvatarIdentity(const QUuid& parentID, const QByteArray& identityData, bool& identityChanged, bool& displayNameChanged); void removeReplicas(const QUuid& parentID); @@ -53,9 +53,11 @@ public: void processDeletedTraitInstance(const QUuid& parentID, AvatarTraits::TraitType traitType, AvatarTraits::TraitInstanceID instanceID); void processTraitInstance(const QUuid& parentID, AvatarTraits::TraitType traitType, AvatarTraits::TraitInstanceID instanceID, QByteArray traitBinaryData); + void setReplicaCount(int count) { _replicaCount = count; } private: std::map> _replicasMap; + int _replicaCount; }; @@ -92,6 +94,12 @@ public: // Null/Default-constructed QUuids will return MyAvatar Q_INVOKABLE virtual ScriptAvatarData* getAvatar(QUuid avatarID) { return new ScriptAvatarData(getAvatarBySessionID(avatarID)); } + /**jsdoc + * @function AvatarList.setReplicaCount + * @param {number} count // The times an avatar will get replicated + */ + Q_INVOKABLE void setReplicaCount(int count); + virtual AvatarSharedPointer getAvatarBySessionID(const QUuid& sessionID) const { return findAvatar(sessionID); } int numberOfAvatarsInRange(const glm::vec3& position, float rangeMeters); From 44a6c7df5f1b648796d8f45fc419acea8c774873 Mon Sep 17 00:00:00 2001 From: Angus Antley Date: Fri, 24 Aug 2018 07:17:17 +0100 Subject: [PATCH 094/545] added hook to myskeleton model to update spine2, need to get the rotation from myavatar then we have spine rot --- interface/src/avatar/MyAvatar.cpp | 4 +++- interface/src/avatar/MySkeletonModel.cpp | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 8d9c503e5e..2771f567b3 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -476,11 +476,13 @@ void MyAvatar::update(float deltaTime) { // draw hand azimuth vector + glm::vec3 handAzimuthMidpoint = transformPoint(getTransform().getMatrix(), glm::vec3(_hipToHandController.x, 0.0f, _hipToHandController.y)); glm::vec3 worldRHandAzimuth = transformPoint(getTransform().getMatrix(), getControllerPoseInAvatarFrame(controller::Action::RIGHT_HAND).getTranslation()); glm::vec3 worldLHandAzimuth = transformPoint(getTransform().getMatrix(), getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND).getTranslation()); qCDebug(interfaceapp) << "the right hand in avatar space" << worldRHandAzimuth << " " << getWorldPosition(); DebugDraw::getInstance().drawRay(getWorldPosition(), worldRHandAzimuth, glm::vec4(0.0f, 1.0f, 0.0f, 1.0f)); DebugDraw::getInstance().drawRay(getWorldPosition(), worldLHandAzimuth, glm::vec4(0.0f, 1.0f, 0.0f, 1.0f)); + DebugDraw::getInstance().drawRay(getWorldPosition(), handAzimuthMidpoint, glm::vec4(0.0f, 1.0f, 1.0f, 1.0f)); } #endif @@ -818,7 +820,7 @@ void MyAvatar::computeHandAzimuth() { //qCDebug(interfaceapp) << "the right hand in avatar space" << rightHandRigSpace; - _hipToHandController = glm::vec2(rightHandRigSpace.x, rightHandRigSpace.z); + _hipToHandController = lerp(glm::vec2(rightHandRigSpace.x, rightHandRigSpace.z), glm::vec2(leftHandRigSpace.x, leftHandRigSpace.z),0.5f); } diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 0fc5e7521e..491fab466d 100644 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -238,6 +238,14 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { params.primaryControllerPoses[Rig::PrimaryControllerType_Hips] = sensorToRigPose * hips; params.primaryControllerFlags[Rig::PrimaryControllerType_Hips] = (uint8_t)Rig::ControllerFlags::Enabled | (uint8_t)Rig::ControllerFlags::Estimated; + + // spine 2 hack to be improved. + AnimPose newSpinePose; + bool fred = _rig.getAbsoluteJointPoseInRigFrame(_rig.indexOfJoint("Spine2"), newSpinePose); + newSpinePose.rot() = glm::quat(0.7071f, 0.0f, 0.0f, 0.7071f)*newSpinePose.rot(); + params.primaryControllerPoses[Rig::PrimaryControllerType_Spine2] = newSpinePose; + params.primaryControllerFlags[Rig::PrimaryControllerType_Spine2] = (uint8_t)Rig::ControllerFlags::Enabled | (uint8_t)Rig::ControllerFlags::Estimated; + } else { _prevHipsValid = false; } From 25610c75876ba7db1de50f26855582d05a4a9ac2 Mon Sep 17 00:00:00 2001 From: Angus Antley Date: Fri, 24 Aug 2018 11:04:36 +0100 Subject: [PATCH 095/545] got the hands turning the shoulders, needs error checking --- interface/src/avatar/MyAvatar.cpp | 15 +++++++++++++++ interface/src/avatar/MyAvatar.h | 2 ++ interface/src/avatar/MySkeletonModel.cpp | 5 ++--- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 2771f567b3..97179f5d22 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -3349,6 +3349,21 @@ glm::mat4 MyAvatar::deriveBodyFromHMDSensor() const { return createMatFromQuatAndPos(headOrientationYawOnly, bodyPos); } +glm::mat4 MyAvatar::getSpine2RotationRigSpace() const { + + static const glm::quat RIG_CHANGE_OF_BASIS = Quaternions::Y_180; + glm::vec3 hipToHandRigSpace = RIG_CHANGE_OF_BASIS * glm::vec3(_hipToHandController.x, 0.0f, _hipToHandController.y); + + //to do: check for zero before normalizing. + glm::vec3 u, v, w; + generateBasisVectors(glm::vec3(0.0f,1.0f,0.0f), hipToHandRigSpace, u, v, w); + glm::mat4 spine2RigSpace(glm::vec4(w, 0.0f), glm::vec4(u, 0.0f), glm::vec4(v, 0.0f), glm::vec4(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f)); + + //glm::quat spine2RigSpace = glm::quat_cast(glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::normalize(hipToHandRigSpace), glm::vec3(0.0f, 1.0f, 0.0f))); + + return spine2RigSpace; +} + // ease in function for dampening cg movement static float slope(float num) { const float CURVE_CONSTANT = 1.0f; diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 6b7c4e83a1..3c951264e8 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -1050,6 +1050,8 @@ public: // results are in sensor frame (-z forward) glm::mat4 deriveBodyFromHMDSensor() const; + glm::mat4 getSpine2RotationRigSpace() const; + glm::vec3 computeCounterBalance(); // derive avatar body position and orientation from using the current HMD Sensor location in relation to the previous diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 491fab466d..5272b1499d 100644 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -240,9 +240,8 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { // spine 2 hack to be improved. - AnimPose newSpinePose; - bool fred = _rig.getAbsoluteJointPoseInRigFrame(_rig.indexOfJoint("Spine2"), newSpinePose); - newSpinePose.rot() = glm::quat(0.7071f, 0.0f, 0.0f, 0.7071f)*newSpinePose.rot(); + AnimPose newSpinePose(myAvatar->getSpine2RotationRigSpace()); + //newSpinePose.rot() = myAvatar->getSpine2RotationRigSpace();// *newSpinePose.rot(); params.primaryControllerPoses[Rig::PrimaryControllerType_Spine2] = newSpinePose; params.primaryControllerFlags[Rig::PrimaryControllerType_Spine2] = (uint8_t)Rig::ControllerFlags::Enabled | (uint8_t)Rig::ControllerFlags::Estimated; From 5654acf5bf28c9476402a1bc6a2cb4ef3545bf07 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Fri, 24 Aug 2018 09:24:58 -0700 Subject: [PATCH 096/545] Fix warnings --- libraries/avatars/src/AvatarHashMap.cpp | 99 ++----------------------- libraries/avatars/src/AvatarHashMap.h | 8 +- 2 files changed, 15 insertions(+), 92 deletions(-) diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index 6949efc19c..67cc9f0563 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -36,7 +36,7 @@ std::vector AvatarReplicas::getReplicaIDs(const QUuid& parentID) { std::vector ids; if (_replicasMap.find(parentID) != _replicasMap.end()) { auto &replicas = _replicasMap[parentID]; - for (int i = 0; i < replicas.size(); i++) { + for (int i = 0; i < (int)replicas.size(); i++) { ids.push_back(replicas[i]->getID()); } } else if (_replicaCount > 0) { @@ -288,92 +288,12 @@ void AvatarHashMap::processAvatarIdentityPacket(QSharedPointer // In this case, the "sendingNode" is the Avatar Mixer. avatar->processAvatarIdentity(message->getMessage(), identityChanged, displayNameChanged); _replicas.processAvatarIdentity(identityUUID, message->getMessage(), identityChanged, displayNameChanged); - } -} -void AvatarHashMap::processBulkAvatarTraitsForID(QUuid sessionUUID, QSharedPointer message, SharedNodePointer sendingNode) { - message->seek(0); - while (message->getBytesLeftToRead()) { - // read the avatar ID to figure out which avatar this is for - auto avatarID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); - avatarID = sessionUUID; - - // grab the avatar so we can ask it to process trait data - bool isNewAvatar; - auto avatar = newOrExistingAvatar(avatarID, sendingNode, isNewAvatar); - - // read the first trait type for this avatar - AvatarTraits::TraitType traitType; - message->readPrimitive(&traitType); - - // grab the last trait versions for this avatar - auto& lastProcessedVersions = _processedTraitVersions[avatarID]; - - while (traitType != AvatarTraits::NullTrait) { - AvatarTraits::TraitVersion packetTraitVersion; - message->readPrimitive(&packetTraitVersion); - - AvatarTraits::TraitWireSize traitBinarySize; - bool skipBinaryTrait = false; - - - if (AvatarTraits::isSimpleTrait(traitType)) { - message->readPrimitive(&traitBinarySize); - - // check if this trait version is newer than what we already have for this avatar - if (packetTraitVersion > lastProcessedVersions[traitType]) { - avatar->processTrait(traitType, message->read(traitBinarySize)); - lastProcessedVersions[traitType] = packetTraitVersion; - } - else { - skipBinaryTrait = true; - } - } - else { - AvatarTraits::TraitInstanceID traitInstanceID = - QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); - - message->readPrimitive(&traitBinarySize); - - auto& processedInstanceVersion = lastProcessedVersions.getInstanceValueRef(traitType, traitInstanceID); - if (packetTraitVersion > processedInstanceVersion) { - if (traitBinarySize == AvatarTraits::DELETED_TRAIT_SIZE) { - avatar->processDeletedTraitInstance(traitType, traitInstanceID); - } - else { - avatar->processTraitInstance(traitType, traitInstanceID, message->read(traitBinarySize)); - } - processedInstanceVersion = packetTraitVersion; - } - else { - skipBinaryTrait = true; - } - } - - if (skipBinaryTrait) { - // we didn't read this trait because it was older or because we didn't have an avatar to process it for - message->seek(message->getPosition() + traitBinarySize); - } - - // read the next trait type, which is null if there are no more traits for this avatar - message->readPrimitive(&traitType); - } } } void AvatarHashMap::processBulkAvatarTraits(QSharedPointer message, SharedNodePointer sendingNode) { - /* - while (message->getBytesLeftToRead()) { - // read the avatar ID to figure out which avatar this is for - auto avatarID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); - processBulkAvatarTraitsForID(avatarID, message, sendingNode); - auto replicaIDs = _replicas.getReplicaIDs(avatarID); - for (auto id : replicaIDs) { - processBulkAvatarTraitsForID(id, message, sendingNode); - } - } - */ - int position = 0; + while (message->getBytesLeftToRead()) { // read the avatar ID to figure out which avatar this is for auto avatarID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); @@ -381,7 +301,6 @@ void AvatarHashMap::processBulkAvatarTraits(QSharedPointer mess // grab the avatar so we can ask it to process trait data bool isNewAvatar; auto avatar = newOrExistingAvatar(avatarID, sendingNode, isNewAvatar); - // read the first trait type for this avatar AvatarTraits::TraitType traitType; message->readPrimitive(&traitType); @@ -402,10 +321,9 @@ void AvatarHashMap::processBulkAvatarTraits(QSharedPointer mess // check if this trait version is newer than what we already have for this avatar if (packetTraitVersion > lastProcessedVersions[traitType]) { - position = message->getPosition(); - avatar->processTrait(traitType, message->read(traitBinarySize)); - message->seek(position); - _replicas.processTrait(avatarID, traitType, message->read(traitBinarySize)); + auto traitData = message->read(traitBinarySize); + avatar->processTrait(traitType, traitData); + _replicas.processTrait(avatarID, traitType, traitData); lastProcessedVersions[traitType] = packetTraitVersion; } else { @@ -425,10 +343,9 @@ void AvatarHashMap::processBulkAvatarTraits(QSharedPointer mess _replicas.processDeletedTraitInstance(avatarID, traitType, traitInstanceID); } else { - position = message->getPosition(); - avatar->processTraitInstance(traitType, traitInstanceID, message->read(traitBinarySize)); - message->seek(position); - _replicas.processTraitInstance(avatarID, traitType, traitInstanceID, message->read(traitBinarySize)); + auto traitData = message->read(traitBinarySize); + avatar->processTraitInstance(traitType, traitInstanceID, traitData); + _replicas.processTraitInstance(avatarID, traitType, traitInstanceID, traitData); } processedInstanceVersion = packetTraitVersion; } diff --git a/libraries/avatars/src/AvatarHashMap.h b/libraries/avatars/src/AvatarHashMap.h index b7199d25ac..97c54e1787 100644 --- a/libraries/avatars/src/AvatarHashMap.h +++ b/libraries/avatars/src/AvatarHashMap.h @@ -54,6 +54,7 @@ public: void processTraitInstance(const QUuid& parentID, AvatarTraits::TraitType traitType, AvatarTraits::TraitInstanceID instanceID, QByteArray traitBinaryData); void setReplicaCount(int count) { _replicaCount = count; } + int getReplicaCount() { return _replicaCount; } private: std::map> _replicasMap; @@ -99,6 +100,12 @@ public: * @param {number} count // The times an avatar will get replicated */ Q_INVOKABLE void setReplicaCount(int count); + + /**jsdoc + * @function AvatarList.setReplicaCount + * @param {number} count // The times an avatar will get replicated + */ + Q_INVOKABLE int getReplicaCount() { return _replicas.getReplicaCount(); }; virtual AvatarSharedPointer getAvatarBySessionID(const QUuid& sessionID) const { return findAvatar(sessionID); } int numberOfAvatarsInRange(const glm::vec3& position, float rangeMeters); @@ -160,7 +167,6 @@ protected slots: */ void processAvatarIdentityPacket(QSharedPointer message, SharedNodePointer sendingNode); - void processBulkAvatarTraitsForID(QUuid sessionUUID, QSharedPointer message, SharedNodePointer sendingNode); void processBulkAvatarTraits(QSharedPointer message, SharedNodePointer sendingNode); /**jsdoc From a60ab863a39a78653a680b06d3886f2ca5d5c646 Mon Sep 17 00:00:00 2001 From: amantley Date: Fri, 24 Aug 2018 11:06:36 -0700 Subject: [PATCH 097/545] demo version of the head and hands determining the rotate function --- interface/src/avatar/MyAvatar.cpp | 45 +++++++++++++++--------- interface/src/avatar/MyAvatar.h | 2 +- interface/src/avatar/MySkeletonModel.cpp | 5 ++- scripts/developer/rotateApp.js | 7 ++-- 4 files changed, 38 insertions(+), 21 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 97179f5d22..a1e30144ee 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -449,7 +449,18 @@ void MyAvatar::update(float deltaTime) { const float HMD_FACING_TIMESCALE = getRotationRecenterFilterLength(); float tau = deltaTime / HMD_FACING_TIMESCALE; - _headControllerFacingMovingAverage = lerp(_headControllerFacingMovingAverage, _headControllerFacing, tau); + + // put the spine facing in sensor space. + // then mix it with head facing to determine rotation recenter + glm::vec3 handHipAzimuthWorldSpace = transformVectorFast(getTransform().getMatrix(), glm::vec3(_hipToHandController.x, 0.0f, _hipToHandController.y)); + glm::mat4 sensorToWorldMat = getSensorToWorldMatrix(); + glm::mat4 worldToSensorMat = glm::inverse(sensorToWorldMat); + glm::vec3 handHipAzimuthSensorSpace = transformVectorFast(worldToSensorMat, glm::vec3(handHipAzimuthWorldSpace.x, 0.0f, handHipAzimuthWorldSpace.z)); + glm::vec2 normedHandHip = glm::normalize(glm::vec2(handHipAzimuthSensorSpace.x, handHipAzimuthSensorSpace.z)); + glm::vec2 headFacingPlusHandHipAzimuthMix = lerp(normedHandHip, _headControllerFacing, 0.5f); + //qCDebug(interfaceapp) << "the hand hip azimuth " << normedHandHip << "the head look at" << _headControllerFacing; + _headControllerFacingMovingAverage = lerp(_headControllerFacingMovingAverage, headFacingPlusHandHipAzimuthMix, tau); + qCDebug(interfaceapp) << "the hand hip azimuth average " << _headControllerFacingMovingAverage; if (_smoothOrientationTimer < SMOOTH_TIME_ORIENTATION) { _rotationChanged = usecTimestampNow(); @@ -479,7 +490,7 @@ void MyAvatar::update(float deltaTime) { glm::vec3 handAzimuthMidpoint = transformPoint(getTransform().getMatrix(), glm::vec3(_hipToHandController.x, 0.0f, _hipToHandController.y)); glm::vec3 worldRHandAzimuth = transformPoint(getTransform().getMatrix(), getControllerPoseInAvatarFrame(controller::Action::RIGHT_HAND).getTranslation()); glm::vec3 worldLHandAzimuth = transformPoint(getTransform().getMatrix(), getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND).getTranslation()); - qCDebug(interfaceapp) << "the right hand in avatar space" << worldRHandAzimuth << " " << getWorldPosition(); + //qCDebug(interfaceapp) << "the right hand in avatar space" << worldRHandAzimuth << " " << getWorldPosition(); DebugDraw::getInstance().drawRay(getWorldPosition(), worldRHandAzimuth, glm::vec4(0.0f, 1.0f, 0.0f, 1.0f)); DebugDraw::getInstance().drawRay(getWorldPosition(), worldLHandAzimuth, glm::vec4(0.0f, 1.0f, 0.0f, 1.0f)); DebugDraw::getInstance().drawRay(getWorldPosition(), handAzimuthMidpoint, glm::vec4(0.0f, 1.0f, 1.0f, 1.0f)); @@ -815,13 +826,17 @@ void MyAvatar::computeHandAzimuth() { auto leftHandPoseAvatarSpace = getLeftHandPose(); auto rightHandPoseAvatarSpace = getRightHandPose(); glm::vec3 localLookat(0.0f, 0.0f, 1.0f); - glm::vec3 rightHandRigSpace = rightHandPoseAvatarSpace.translation;// transformVectorFast(getTransform().getMatrix(), rightHandPoseAvatarSpace.translation); - glm::vec3 leftHandRigSpace = leftHandPoseAvatarSpace.translation;// transformVectorFast(getTransform().getMatrix(), leftHandPoseAvatarSpace.translation); - - //qCDebug(interfaceapp) << "the right hand in avatar space" << rightHandRigSpace; - - _hipToHandController = lerp(glm::vec2(rightHandRigSpace.x, rightHandRigSpace.z), glm::vec2(leftHandRigSpace.x, leftHandRigSpace.z),0.5f); + // glm::vec3 rightHandRigSpace = rightHandPoseAvatarSpace.translation;// transformVectorFast(getTransform().getMatrix(), rightHandPoseAvatarSpace.translation); + // glm::vec3 leftHandRigSpace = leftHandPoseAvatarSpace.translation;// transformVectorFast(getTransform().getMatrix(), leftHandPoseAvatarSpace.translation); + // qCDebug(interfaceapp) << "the right hand in avatar space" << rightHandRigSpace; + if (leftHandPoseAvatarSpace.isValid() && rightHandPoseAvatarSpace.isValid()) { + _hipToHandController = lerp(glm::normalize(glm::vec2(rightHandPoseAvatarSpace.translation.x, rightHandPoseAvatarSpace.translation.z)), glm::normalize(glm::vec2(leftHandPoseAvatarSpace.translation.x, leftHandPoseAvatarSpace.translation.z)), 0.5f); + //need to use easing function here. + //var rotateAngle = ((Math.cos((leftRightMidpoint / 180.0) * Math.PI) + 2.0) / 3.0) * leftRightMidpoint; + } else { + _hipToHandController = glm::vec2(0.0f, 1.0f); + } } void MyAvatar::updateJointFromController(controller::Action poseKey, ThreadSafeValueCache& matrixCache) { @@ -3359,8 +3374,6 @@ glm::mat4 MyAvatar::getSpine2RotationRigSpace() const { generateBasisVectors(glm::vec3(0.0f,1.0f,0.0f), hipToHandRigSpace, u, v, w); glm::mat4 spine2RigSpace(glm::vec4(w, 0.0f), glm::vec4(u, 0.0f), glm::vec4(v, 0.0f), glm::vec4(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f)); - //glm::quat spine2RigSpace = glm::quat_cast(glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::normalize(hipToHandRigSpace), glm::vec3(0.0f, 1.0f, 0.0f))); - return spine2RigSpace; } @@ -3977,15 +3990,15 @@ void MyAvatar::FollowHelper::prePhysicsUpdate(MyAvatar& myAvatar, const glm::mat if (myAvatar.getHMDLeanRecenterEnabled() && qApp->getCamera().getMode() != CAMERA_MODE_MIRROR) { - if (!isActive(Rotation) && getForceActivateRotation()) { - activate(Rotation); - myAvatar.setHeadControllerFacingMovingAverage(myAvatar._headControllerFacing); - setForceActivateRotation(false); - } - //if (!isActive(Rotation) && (shouldActivateRotation(myAvatar, desiredBodyMatrix, currentBodyMatrix) || hasDriveInput)) { + //if (!isActive(Rotation) && getForceActivateRotation()) { // activate(Rotation); // myAvatar.setHeadControllerFacingMovingAverage(myAvatar._headControllerFacing); + // setForceActivateRotation(false); //} + if (!isActive(Rotation) && (shouldActivateRotation(myAvatar, desiredBodyMatrix, currentBodyMatrix) || hasDriveInput)) { + activate(Rotation); + myAvatar.setHeadControllerFacingMovingAverage(myAvatar._headControllerFacing); + } if (myAvatar.getCenterOfGravityModelEnabled()) { if ((!isActive(Horizontal) && (shouldActivateHorizontalCG(myAvatar) || hasDriveInput)) || (isActive(Horizontal) && (currentVelocity > VELOCITY_THRESHHOLD))) { activate(Horizontal); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 3c951264e8..177b453267 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -1663,7 +1663,7 @@ private: glm::vec2 _headControllerFacingMovingAverage { 0.0f, 0.0f }; // facing vector in xz plane (sensor space) glm::quat _averageHeadRotation { 0.0f, 0.0f, 0.0f, 1.0f }; - glm::vec2 _hipToHandController; // facing vector in xz plane (sensor space) + glm::vec2 _hipToHandController; // spine2 facing vector in xz plane (avatar space) float _currentStandingHeight { 0.0f }; bool _resetMode { true }; diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 5272b1499d..158f9bb0b6 100644 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -240,9 +240,12 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { // spine 2 hack to be improved. + AnimPose currentPose; + bool ret = _rig.getAbsoluteJointPoseInRigFrame(_rig.indexOfJoint("Spine2"),currentPose); AnimPose newSpinePose(myAvatar->getSpine2RotationRigSpace()); + currentPose.rot() = newSpinePose.rot(); //newSpinePose.rot() = myAvatar->getSpine2RotationRigSpace();// *newSpinePose.rot(); - params.primaryControllerPoses[Rig::PrimaryControllerType_Spine2] = newSpinePose; + params.primaryControllerPoses[Rig::PrimaryControllerType_Spine2] = currentPose; params.primaryControllerFlags[Rig::PrimaryControllerType_Spine2] = (uint8_t)Rig::ControllerFlags::Enabled | (uint8_t)Rig::ControllerFlags::Estimated; } else { diff --git a/scripts/developer/rotateApp.js b/scripts/developer/rotateApp.js index e4080c9bb0..030385b6fb 100644 --- a/scripts/developer/rotateApp.js +++ b/scripts/developer/rotateApp.js @@ -29,6 +29,7 @@ var spine2Rotation = { x: 0, y: 0, z: 0, w: 1 }; var hipToLHandAverage = { x: 0, y: 0, z: 0, w: 1 }; var hipToRHandAverage = { x: 0, y: 0, z: 0, w: 1 }; +/* var ikTypes = { RotationAndPosition: 0, RotationOnly: 1, @@ -65,7 +66,7 @@ var handlerId = MyAvatar.addAnimationStateHandler(function (props) { return result; }, ANIM_VARS); - +*/ // define state readings constructor function StateReading(headPose, rhandPose, lhandPose, diffFromAverageEulers) { this.headPose = headPose; @@ -298,7 +299,7 @@ function computeHandAzimuths(timeElapsed) { var raySpineRotation = Quat.fromVec3Degrees({ x: 0, y: leftRightMidpointAverage, z: 0 }); var zAxisSpineRotation = Vec3.multiplyQbyV(raySpineRotation, { x: 0, y: 0, z: -1 }); var zAxisWorldSpace = Vec3.multiplyQbyV(MyAvatar.orientation, zAxisSpineRotation); - DebugDraw.drawRay(MyAvatar.position, Vec3.sum(MyAvatar.position, zAxisWorldSpace), { x: 1, y: 0, z: 0, w: 1 }); + // DebugDraw.drawRay(MyAvatar.position, Vec3.sum(MyAvatar.position, zAxisWorldSpace), { x: 1, y: 0, z: 0, w: 1 }); //print(leftRightMidpoint); @@ -312,7 +313,7 @@ function computeHandAzimuths(timeElapsed) { var headPlusHands = (leftRightMidpointAverage + headPoseAverageEulers.y) / 2.0; if ((Math.abs(headPlusHands / 180.0) * Math.PI) > angleThresholdProperty.value) { //print("recenter the feet under the head"); - MyAvatar.triggerRotationRecenter(); + // MyAvatar.triggerRotationRecenter(); hipToLHandAverage = { x: 0, y: 0, z: 0, w: 1 }; hipToRHandAverage = { x: 0, y: 0, z: 0, w: 1 }; headPoseAverageOrientation = { x: 0, y: 0, z: 0, w: 1 }; From 1c0c17cecbb879901301feaaa73b0868a5f1335e Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 24 Aug 2018 11:20:10 -0700 Subject: [PATCH 098/545] faster triangle intersection --- libraries/shared/src/GeometryUtil.cpp | 38 +++++++++++++++++---------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/libraries/shared/src/GeometryUtil.cpp b/libraries/shared/src/GeometryUtil.cpp index a93c2ec9f3..c69b05db53 100644 --- a/libraries/shared/src/GeometryUtil.cpp +++ b/libraries/shared/src/GeometryUtil.cpp @@ -392,24 +392,34 @@ Triangle Triangle::operator*(const glm::mat4& transform) const { }; } +// https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm bool findRayTriangleIntersection(const glm::vec3& origin, const glm::vec3& direction, const glm::vec3& v0, const glm::vec3& v1, const glm::vec3& v2, float& distance, bool allowBackface) { - glm::vec3 firstSide = v0 - v1; - glm::vec3 secondSide = v2 - v1; - glm::vec3 normal = glm::cross(secondSide, firstSide); - float dividend = glm::dot(normal, v1) - glm::dot(origin, normal); - if (!allowBackface && dividend > 0.0f) { - return false; // origin below plane - } - float divisor = glm::dot(normal, direction); - if (divisor >= 0.0f) { + glm::vec3 firstSide = v1 - v0; + glm::vec3 secondSide = v2 - v0; + glm::vec3 P = glm::cross(direction, secondSide); + float det = glm::dot(firstSide, P); + if (!allowBackface && det < EPSILON) { + return false; + } else if (fabsf(det) < EPSILON) { return false; } - float t = dividend / divisor; - glm::vec3 point = origin + direction * t; - if (glm::dot(normal, glm::cross(point - v1, firstSide)) > 0.0f && - glm::dot(normal, glm::cross(secondSide, point - v1)) > 0.0f && - glm::dot(normal, glm::cross(point - v0, v2 - v0)) > 0.0f) { + + float invDet = 1.0f / det; + glm::vec3 T = origin - v0; + float u = glm::dot(T, P) * invDet; + if (u < 0.0f || u > 1.0f) { + return false; + } + + glm::vec3 Q = glm::cross(T, firstSide); + float v = glm::dot(direction, Q) * invDet; + if (v < 0.0f || u + v > 1.0f) { + return false; + } + + float t = glm::dot(secondSide, Q) * invDet; + if (t > EPSILON) { distance = t; return true; } From 30c6975198c7e15f55c6b37f1e1975d708d541fe Mon Sep 17 00:00:00 2001 From: David Back Date: Fri, 24 Aug 2018 11:53:03 -0700 Subject: [PATCH 099/545] maintain stretch cube position vs mouse when stretching --- .../system/libraries/entitySelectionTool.js | 100 +++++++++++------- 1 file changed, 61 insertions(+), 39 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index f251a1611c..2478160293 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -495,6 +495,8 @@ SelectionDisplay = (function() { var worldRotationX; var worldRotationY; var worldRotationZ; + + var activeStretchCubePanelOffset = null; var previousHandle = null; var previousHandleHelper = null; @@ -1435,34 +1437,7 @@ SelectionDisplay = (function() { Overlays.editOverlay(handleScaleNLEdge, { start: LTNPosition, end: LBNPosition }); Overlays.editOverlay(handleScaleFREdge, { start: RTFPosition, end: RBFPosition }); Overlays.editOverlay(handleScaleFLEdge, { start: LTFPosition, end: LBFPosition }); - - // UPDATE STRETCH CUBES - var stretchCubeDimension = rotateDimension * STRETCH_CUBE_CAMERA_DISTANCE_MULTIPLE / - ROTATE_RING_CAMERA_DISTANCE_MULTIPLE; - var stretchCubeDimensions = { x: stretchCubeDimension, y: stretchCubeDimension, z: stretchCubeDimension }; - var stretchCubeOffset = rotateDimension * STRETCH_CUBE_OFFSET / ROTATE_RING_CAMERA_DISTANCE_MULTIPLE; - var stretchXPosition = { x: stretchCubeOffset, y: 0, z: 0 }; - stretchXPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, stretchXPosition)); - Overlays.editOverlay(handleStretchXCube, { - position: stretchXPosition, - rotation: rotationX, - dimensions: stretchCubeDimensions - }); - var stretchYPosition = { x: 0, y: stretchCubeOffset, z: 0 }; - stretchYPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, stretchYPosition)); - Overlays.editOverlay(handleStretchYCube, { - position: stretchYPosition, - rotation: rotationY, - dimensions: stretchCubeDimensions - }); - var stretchZPosition = { x: 0, y: 0, z: stretchCubeOffset }; - stretchZPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, stretchZPosition)); - Overlays.editOverlay(handleStretchZCube, { - position: stretchZPosition, - rotation: rotationZ, - dimensions: stretchCubeDimensions - }); - + // UPDATE STRETCH HIGHLIGHT PANELS var RBFPositionRotated = Vec3.multiplyQbyV(rotationInverse, RBFPosition); var RTFPositionRotated = Vec3.multiplyQbyV(rotationInverse, RTFPosition); @@ -1502,6 +1477,46 @@ SelectionDisplay = (function() { dimensions: stretchPanelZDimensions }); + // UPDATE STRETCH CUBES + var stretchCubeDimension = rotateDimension * STRETCH_CUBE_CAMERA_DISTANCE_MULTIPLE / + ROTATE_RING_CAMERA_DISTANCE_MULTIPLE; + var stretchCubeDimensions = { x: stretchCubeDimension, y: stretchCubeDimension, z: stretchCubeDimension }; + var stretchCubeOffset = rotateDimension * STRETCH_CUBE_OFFSET / ROTATE_RING_CAMERA_DISTANCE_MULTIPLE; + var stretchXPosition, stretchYPosition, stretchZPosition; + if (isActiveTool(handleStretchXCube)) { + stretchXPosition = Vec3.subtract(stretchPanelXPosition, activeStretchCubePanelOffset); + } else { + stretchXPosition = { x: stretchCubeOffset, y: 0, z: 0 }; + stretchXPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, stretchXPosition)); + } + if (isActiveTool(handleStretchYCube)) { + stretchYPosition = Vec3.subtract(stretchPanelYPosition, activeStretchCubePanelOffset); + } else { + stretchYPosition = { x: 0, y: stretchCubeOffset, z: 0 }; + stretchYPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, stretchYPosition)); + } + if (isActiveTool(handleStretchZCube)) { + stretchZPosition = Vec3.subtract(stretchPanelZPosition, activeStretchCubePanelOffset); + } else { + stretchZPosition = { x: 0, y: 0, z: stretchCubeOffset }; + stretchZPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, stretchZPosition)); + } + Overlays.editOverlay(handleStretchXCube, { + position: stretchXPosition, + rotation: rotationX, + dimensions: stretchCubeDimensions + }); + Overlays.editOverlay(handleStretchYCube, { + position: stretchYPosition, + rotation: rotationY, + dimensions: stretchCubeDimensions + }); + Overlays.editOverlay(handleStretchZCube, { + position: stretchZPosition, + rotation: rotationZ, + dimensions: stretchCubeDimensions + }); + // UPDATE SELECTION BOX (CURRENTLY INVISIBLE WITH 0 ALPHA FOR TRANSLATE XZ TOOL) var inModeRotate = isActiveTool(handleRotatePitchRing) || isActiveTool(handleRotateYawRing) || @@ -2035,7 +2050,7 @@ SelectionDisplay = (function() { }; // TOOL DEFINITION: HANDLE STRETCH TOOL - function makeStretchTool(stretchMode, directionEnum, directionVec, pivot, offset, stretchPanel, scaleHandle) { + function makeStretchTool(stretchMode, directionEnum, directionVec, pivot, offset, stretchPanel, cubeHandle) { var directionFor3DStretch = directionVec; var distanceFor3DStretch = 0; var DISTANCE_INFLUENCE_THRESHOLD = 1.2; @@ -2069,7 +2084,9 @@ SelectionDisplay = (function() { var previousPickRay = null; var beginMouseEvent = null; - var onBegin = function(event, pickRay, pickResult) { + var onBegin = function(event, pickRay, pickResult) { + var proportional = directionEnum === STRETCH_DIRECTION.ALL; + var properties = Entities.getEntityProperties(SelectionManager.selections[0]); initialProperties = properties; rotation = (spaceMode === SPACE_LOCAL) ? properties.rotation : Quat.IDENTITY; @@ -2185,10 +2202,7 @@ SelectionDisplay = (function() { if (stretchPanel !== null) { Overlays.editOverlay(stretchPanel, { visible: true }); } - if (scaleHandle !== null) { - Overlays.editOverlay(scaleHandle, { color: COLOR_SCALE_CUBE_SELECTED }); - } - + var collisionToRemove = "myAvatar"; if (properties.collidesWith.indexOf(collisionToRemove) > -1) { var newCollidesWith = properties.collidesWith.replace(collisionToRemove, ""); @@ -2196,6 +2210,12 @@ SelectionDisplay = (function() { that.replaceCollisionsAfterStretch = true; } + if (!proportional) { + var stretchCubePosition = Overlays.getProperty(cubeHandle, "position"); + var stretchPanelPosition = Overlays.getProperty(stretchPanel, "position"); + activeStretchCubePanelOffset = Vec3.subtract(stretchPanelPosition, stretchCubePosition); + } + previousPickRay = pickRay; beginMouseEvent = event; }; @@ -2204,9 +2224,6 @@ SelectionDisplay = (function() { if (stretchPanel !== null) { Overlays.editOverlay(stretchPanel, { visible: false }); } - if (scaleHandle !== null) { - Overlays.editOverlay(scaleHandle, { color: COLOR_SCALE_CUBE }); - } if (that.replaceCollisionsAfterStretch) { var newCollidesWith = SelectionManager.savedProperties[SelectionManager.selections[0]].collidesWith; @@ -2214,6 +2231,8 @@ SelectionDisplay = (function() { that.replaceCollisionsAfterStretch = false; } + activeStretchCubePanelOffset = null; + pushCommandForSelections(); }; @@ -2347,19 +2366,22 @@ SelectionDisplay = (function() { } function addHandleStretchTool(overlay, mode, directionEnum) { - var directionVector, offset, stretchPanel; + var directionVector, offset, stretchPanel, handleStretchCube; if (directionEnum === STRETCH_DIRECTION.X) { stretchPanel = handleStretchXPanel; + handleStretchCube = handleStretchXCube; directionVector = { x: -1, y: 0, z: 0 }; } else if (directionEnum === STRETCH_DIRECTION.Y) { stretchPanel = handleStretchYPanel; + handleStretchCube = handleStretchYCube; directionVector = { x: 0, y: -1, z: 0 }; } else if (directionEnum === STRETCH_DIRECTION.Z) { stretchPanel = handleStretchZPanel; + handleStretchCube = handleStretchZCube; directionVector = { x: 0, y: 0, z: -1 }; } offset = Vec3.multiply(directionVector, NEGATE_VECTOR); - var tool = makeStretchTool(mode, directionEnum, directionVector, directionVector, offset, stretchPanel, null); + var tool = makeStretchTool(mode, directionEnum, directionVector, directionVector, offset, stretchPanel, handleStretchCube); return addHandleTool(overlay, tool); } From ddbadf5a6936e29a426bd862ffca06129cfd1fac Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Fri, 24 Aug 2018 11:59:46 -0700 Subject: [PATCH 100/545] change to Test API --- interface/src/Application.h | 3 +++ .../src/scripting/TestScriptingInterface.cpp | 8 ++++++++ interface/src/scripting/TestScriptingInterface.h | 14 ++++++++++++++ libraries/avatars/src/AvatarHashMap.h | 15 +++------------ 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/interface/src/Application.h b/interface/src/Application.h index 742cf075f6..0d4417cd91 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -311,6 +311,9 @@ public: Q_INVOKABLE void copyToClipboard(const QString& text); + int getOtherAvatarsReplicaCount() { return DependencyManager::get()->getReplicaCount(); } + void setOtherAvatarsReplicaCount(int count) { DependencyManager::get()->setReplicaCount(count); } + #if defined(Q_OS_ANDROID) void beforeEnterBackground(); void enterBackground(); diff --git a/interface/src/scripting/TestScriptingInterface.cpp b/interface/src/scripting/TestScriptingInterface.cpp index 430441226f..52f6a3ebc0 100644 --- a/interface/src/scripting/TestScriptingInterface.cpp +++ b/interface/src/scripting/TestScriptingInterface.cpp @@ -190,4 +190,12 @@ void TestScriptingInterface::saveObject(QVariant variant, const QString& filenam void TestScriptingInterface::showMaximized() { qApp->getWindow()->showMaximized(); +} + +void TestScriptingInterface::setOtherAvatarsReplicaCount(int count) { + qApp->setOtherAvatarsReplicaCount(count); +} + +int TestScriptingInterface::getOtherAvatarsReplicaCount() { + return qApp->getOtherAvatarsReplicaCount(); } \ No newline at end of file diff --git a/interface/src/scripting/TestScriptingInterface.h b/interface/src/scripting/TestScriptingInterface.h index c47e39d1f3..4a1d1a3eeb 100644 --- a/interface/src/scripting/TestScriptingInterface.h +++ b/interface/src/scripting/TestScriptingInterface.h @@ -149,6 +149,20 @@ public slots: */ void showMaximized(); + /**jsdoc + * Values higher than 0 will create replicas of other-avatars when entering a domain for testing purpouses + * @function Test.setOtherAvatarsReplicaCount + * @param {number} count - Number of replicas we want to create + */ + Q_INVOKABLE void setOtherAvatarsReplicaCount(int count); + + /**jsdoc + * Return the number of replicas that are being created of other-avatars when entering a domain + * @function Test.getOtherAvatarsReplicaCount + * @returns {number} Current number of replicas of other-avatars. + */ + Q_INVOKABLE int getOtherAvatarsReplicaCount(); + private: bool waitForCondition(qint64 maxWaitMs, std::function condition); QString _testResultsLocation; diff --git a/libraries/avatars/src/AvatarHashMap.h b/libraries/avatars/src/AvatarHashMap.h index 97c54e1787..e4e197a080 100644 --- a/libraries/avatars/src/AvatarHashMap.h +++ b/libraries/avatars/src/AvatarHashMap.h @@ -95,21 +95,12 @@ public: // Null/Default-constructed QUuids will return MyAvatar Q_INVOKABLE virtual ScriptAvatarData* getAvatar(QUuid avatarID) { return new ScriptAvatarData(getAvatarBySessionID(avatarID)); } - /**jsdoc - * @function AvatarList.setReplicaCount - * @param {number} count // The times an avatar will get replicated - */ - Q_INVOKABLE void setReplicaCount(int count); - - /**jsdoc - * @function AvatarList.setReplicaCount - * @param {number} count // The times an avatar will get replicated - */ - Q_INVOKABLE int getReplicaCount() { return _replicas.getReplicaCount(); }; - virtual AvatarSharedPointer getAvatarBySessionID(const QUuid& sessionID) const { return findAvatar(sessionID); } int numberOfAvatarsInRange(const glm::vec3& position, float rangeMeters); + void setReplicaCount(int count); + int getReplicaCount() { return _replicas.getReplicaCount(); }; + signals: /**jsdoc From cb4ce4fedb8bc6155b71ae08ad074037b750defd Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 24 Aug 2018 13:05:04 -0700 Subject: [PATCH 101/545] make sure settings are re-requested on new connection --- libraries/networking/src/NodeList.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 4e8cbbf9db..e458ffab7e 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -656,7 +656,13 @@ void NodeList::processDomainServerList(QSharedPointer message) ((currentLocalID != Node::NULL_LOCAL_ID && newLocalID != currentLocalID) || (!currentSessionID.isNull() && newUUID != currentSessionID))) { qCDebug(networking) << "Local ID or Session ID changed while connected to domain - forcing NodeList reset"; + + // reset the nodelist, but don't do a domain handler reset since we're about to process a good domain list reset(true); + + // tell the domain handler that we're no longer connected so that below + // it can re-perform actions as if we just connected + _domainHandler.setIsConnected(false); } setSessionLocalID(newLocalID); From d8b5a1a4a6ddd80ec02ce3bce8911c6ff9d9766a Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 24 Aug 2018 14:21:54 -0700 Subject: [PATCH 102/545] always remove old socket-matching node before add --- domain-server/src/DomainGatekeeper.cpp | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/domain-server/src/DomainGatekeeper.cpp b/domain-server/src/DomainGatekeeper.cpp index 2307b1be3b..e23d9e57a8 100644 --- a/domain-server/src/DomainGatekeeper.cpp +++ b/domain-server/src/DomainGatekeeper.cpp @@ -463,19 +463,15 @@ SharedNodePointer DomainGatekeeper::processAgentConnectRequest(const NodeConnect limitedNodeList->eachNodeBreakable([nodeConnection, username, &existingNodeID](const SharedNodePointer& node){ if (node->getPublicSocket() == nodeConnection.publicSockAddr && node->getLocalSocket() == nodeConnection.localSockAddr) { - // we have a node that already has these exact sockets - this can occur if a node - // is failing to connect to the domain - - // we'll re-use the existing node ID - // as long as the user hasn't changed their username (by logging in or logging out) - auto existingNodeData = static_cast(node->getLinkedData()); - - if (existingNodeData->getUsername() == username) { - qDebug() << "Deleting existing connection from same sockaddr: " << node->getUUID(); - existingNodeID = node->getUUID(); - return false; - } + // we have a node that already has these exact sockets + // this can occur if a node is failing to connect to the domain + + // remove the old node before adding the new node + qDebug() << "Deleting existing connection from same sockaddr: " << node->getUUID(); + existingNodeID = node->getUUID(); + return false; } + return true; }); From 98d145dc2487508bcf1d4076892cb6f0cf14e3dc Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 24 Aug 2018 15:19:48 -0700 Subject: [PATCH 103/545] fix crash on shutdown in domain with material --- interface/src/Application.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e290531471..44bba6250b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1841,6 +1841,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo }); EntityTree::setAddMaterialToEntityOperator([this](const QUuid& entityID, graphics::MaterialLayer material, const std::string& parentMaterialName) { + if (_aboutToQuit) { + return false; + } + // try to find the renderable auto renderable = getEntities()->renderableForEntityId(entityID); if (renderable) { @@ -1856,6 +1860,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo return false; }); EntityTree::setRemoveMaterialFromEntityOperator([this](const QUuid& entityID, graphics::MaterialPointer material, const std::string& parentMaterialName) { + if (_aboutToQuit) { + return false; + } + // try to find the renderable auto renderable = getEntities()->renderableForEntityId(entityID); if (renderable) { From ff6020e0ef2489f3cfbe5e883d1688b73a0b3971 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 24 Aug 2018 15:41:25 -0700 Subject: [PATCH 104/545] fix compile errors, maybe --- libraries/render-utils/src/Model.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 4fc8e265ab..71250c6483 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -319,7 +319,7 @@ bool Model::updateGeometry() { // Interleave normals and tangents // Parallel version for performance - tbb::parallel_for(tbb::blocked_range(0, mesh.normals.size()), [&](const tbb::blocked_range& range) { + tbb::parallel_for(tbb::blocked_range(0, mesh.normals.size()), [&](const tbb::blocked_range& range) { auto normalsRange = std::make_pair(mesh.normals.begin() + range.begin(), mesh.normals.begin() + range.end()); auto tangentsRange = std::make_pair(mesh.tangents.begin() + range.begin(), mesh.tangents.begin() + range.end()); auto normalsAndTangentsIt = normalsAndTangents.begin() + 2 * range.begin(); @@ -1281,7 +1281,7 @@ void Blender::run() { } float normalCoefficient = vertexCoefficient * NORMAL_COEFFICIENT_SCALE; const FBXBlendshape& blendshape = mesh.blendshapes.at(i); - tbb::parallel_for(tbb::blocked_range(0, blendshape.indices.size()), [&](const tbb::blocked_range& range) { + tbb::parallel_for(tbb::blocked_range(0, blendshape.indices.size()), [&](const tbb::blocked_range& range) { for (auto j = range.begin(); j < range.end(); j++) { int index = blendshape.indices.at(j); meshVertices[index] += blendshape.vertices.at(j) * vertexCoefficient; From 3796675123214960ed569f7f83c2788a3005a942 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Fri, 24 Aug 2018 15:46:39 -0700 Subject: [PATCH 105/545] script update and visuallyReady entities --- interface/src/Application.cpp | 5 ++- .../src/octree/OctreePacketProcessor.cpp | 4 +++ interface/src/octree/OctreePacketProcessor.h | 1 + interface/src/octree/SafeLanding.cpp | 33 +++++++++++++++---- interface/src/octree/SafeLanding.h | 3 ++ .../src/RenderableModelEntityItem.cpp | 10 +++++- .../src/RenderableModelEntityItem.h | 6 +++- .../src/RenderableZoneEntityItem.cpp | 10 ++++++ libraries/entities/src/EntityItem.h | 3 ++ libraries/entities/src/ModelEntityItem.cpp | 1 + libraries/entities/src/ZoneEntityItem.cpp | 1 + scripts/system/interstitialPage.js | 19 ++++++++--- 12 files changed, 83 insertions(+), 13 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6b2781417d..a4ced55a2d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5519,6 +5519,7 @@ void Application::update(float deltaTime) { return; } + if (!_physicsEnabled) { if (!domainLoadingInProgress) { PROFILE_ASYNC_BEGIN(app, "Scene Loading", ""); @@ -5528,7 +5529,9 @@ void Application::update(float deltaTime) { // we haven't yet enabled physics. we wait until we think we have all the collision information // for nearby entities before starting bullet up. quint64 now = usecTimestampNow(); - if (isServerlessMode() || _octreeProcessor.isLoadSequenceComplete()) { + bool renderReady = _octreeProcessor.isEntitiesRenderReady(); + qDebug() << "--> render ready: " << renderReady; + if (isServerlessMode() || (_octreeProcessor.isLoadSequenceComplete() && renderReady)) { // we've received a new full-scene octree stats packet, or it's been long enough to try again anyway _lastPhysicsCheckTime = now; _fullSceneCounterAtLastPhysicsCheck = _fullSceneReceivedCounter; diff --git a/interface/src/octree/OctreePacketProcessor.cpp b/interface/src/octree/OctreePacketProcessor.cpp index 11f6bbae13..e02c603415 100644 --- a/interface/src/octree/OctreePacketProcessor.cpp +++ b/interface/src/octree/OctreePacketProcessor.cpp @@ -138,6 +138,10 @@ bool OctreePacketProcessor::isLoadSequenceComplete() const { return _safeLanding->isLoadSequenceComplete(); } +bool OctreePacketProcessor::isEntitiesRenderReady() const { + return _safeLanding->entitiesRenderReady(); +} + float OctreePacketProcessor::domainLoadProgress() { return _safeLanding->loadingProgressPercentage(); } diff --git a/interface/src/octree/OctreePacketProcessor.h b/interface/src/octree/OctreePacketProcessor.h index fb8f0b581a..8e771de556 100644 --- a/interface/src/octree/OctreePacketProcessor.h +++ b/interface/src/octree/OctreePacketProcessor.h @@ -27,6 +27,7 @@ public: void startEntitySequence(); bool isLoadSequenceComplete() const; + bool isEntitiesRenderReady() const; float domainLoadProgress(); signals: diff --git a/interface/src/octree/SafeLanding.cpp b/interface/src/octree/SafeLanding.cpp index 4b8edd5934..bdaaa58fcc 100644 --- a/interface/src/octree/SafeLanding.cpp +++ b/interface/src/octree/SafeLanding.cpp @@ -36,6 +36,7 @@ void SafeLanding::startEntitySequence(QSharedPointer entityT if (entityTree) { Locker lock(_lock); _entityTree = entityTree; + _trackedEntitiesRenderStatus.clear(); _trackedEntities.clear(); _trackingEntities = true; connect(std::const_pointer_cast(_entityTree).get(), @@ -76,22 +77,24 @@ void SafeLanding::addTrackedEntity(const EntityItemID& entityID) { if (hasAABox && downloadedCollisionTypes.count(modelEntity->getShapeType()) != 0) { // Only track entities with downloaded collision bodies. _trackedEntities.emplace(entityID, entity); - - float trackedEntityCount = (float)_trackedEntities.size(); - - if (trackedEntityCount > _maxTrackedEntityCount) { - _maxTrackedEntityCount = trackedEntityCount; - } qCDebug(interfaceapp) << "Safe Landing: Tracking entity " << entity->getItemName(); } } } + + _trackedEntitiesRenderStatus.emplace(entityID, entity); + float trackedEntityCount = (float)_trackedEntitiesRenderStatus.size(); + + if (trackedEntityCount > _maxTrackedEntityCount) { + _maxTrackedEntityCount = trackedEntityCount; + } } } void SafeLanding::deleteTrackedEntity(const EntityItemID& entityID) { Locker lock(_lock); _trackedEntities.erase(entityID); + _trackedEntitiesRenderStatus.erase(entityID); } void SafeLanding::setCompletionSequenceNumbers(int first, int last) { @@ -165,6 +168,24 @@ bool SafeLanding::isEntityPhysicsComplete() { return _trackedEntities.empty(); } +bool SafeLanding::entitiesRenderReady() { + Locker lock(_lock); + + for (auto entityMapIter = _trackedEntitiesRenderStatus.begin(); entityMapIter != _trackedEntitiesRenderStatus.end(); ++entityMapIter) { + auto entity = entityMapIter->second; + bool visuallyReady = entity->isVisuallyReady(); + qDebug() << "is entityType: " << EntityTypes::getEntityTypeName(entity->getType()) << " " << visuallyReady; + if (visuallyReady) { + entityMapIter = _trackedEntitiesRenderStatus.erase(entityMapIter); + if (entityMapIter == _trackedEntitiesRenderStatus.end()) { + break; + } + } + } + qDebug() << "list size: -> " << _trackedEntitiesRenderStatus.size(); + return _trackedEntitiesRenderStatus.empty(); +} + float SafeLanding::ElevatedPriority(const EntityItem& entityItem) { return entityItem.getCollisionless() ? 0.0f : 10.0f; } diff --git a/interface/src/octree/SafeLanding.h b/interface/src/octree/SafeLanding.h index 4bede579dc..611b75ab79 100644 --- a/interface/src/octree/SafeLanding.h +++ b/interface/src/octree/SafeLanding.h @@ -18,6 +18,7 @@ #include #include "EntityItem.h" +#include "EntityDynamicInterface.h" class EntityTreeRenderer; class EntityItemID; @@ -29,6 +30,7 @@ public: void setCompletionSequenceNumbers(int first, int last); // 'last' exclusive. void noteReceivedsequenceNumber(int sequenceNumber); bool isLoadSequenceComplete(); + bool entitiesRenderReady(); float loadingProgressPercentage(); private slots: @@ -46,6 +48,7 @@ private: EntityTreePointer _entityTree; using EntityMap = std::map; EntityMap _trackedEntities; + EntityMap _trackedEntitiesRenderStatus; static constexpr int INVALID_SEQUENCE = -1; int _initialStart { INVALID_SEQUENCE }; diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 34936c2c48..c3cc634236 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -1441,7 +1441,7 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce // That is where _currentFrame and _lastAnimated were updated. if (_animating) { DETAILED_PROFILE_RANGE(simulation_physics, "Animate"); - + if (!jointsMapped()) { mapJoints(entity, model->getJointNames()); //else the joint have been mapped before but we have a new animation to load @@ -1457,6 +1457,14 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce } } + +void ModelEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { + withWriteLock([&] { + bool visuallyReady = (_prevModelLoaded && _texturesLoaded); + entity->setVisuallyReady(visuallyReady); + }); +} + void ModelEntityRenderer::setIsVisibleInSecondaryCamera(bool value) { Parent::setIsVisibleInSecondaryCamera(value); setKey(_didLastVisualGeometryRequestSucceed); diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 45892fdd7f..bcf7296456 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -38,11 +38,13 @@ class ModelEntityWrapper : public ModelEntityItem { using Parent = ModelEntityItem; friend class render::entities::ModelEntityRenderer; +public: + bool isModelLoaded() const; + protected: ModelEntityWrapper(const EntityItemID& entityItemID) : Parent(entityItemID) {} void setModel(const ModelPointer& model); ModelPointer getModel() const; - bool isModelLoaded() const; bool _needsInitialSimulation{ true }; private: @@ -162,6 +164,8 @@ protected: virtual void doRender(RenderArgs* args) override; virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override; + virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override; + render::hifi::Tag getTagMask() const override; void setIsVisibleInSecondaryCamera(bool value) override; diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index c5035431f6..598b3d1449 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -258,6 +258,16 @@ void ZoneEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scen if (hazeChanged) { updateHazeFromEntity(entity); } + + bool visuallyReady = true; + uint32_t skyboxMode = entity->getSkyboxMode(); + if (skyboxMode == COMPONENT_MODE_ENABLED) { + bool skyboxLoadedOrFailed = (_skyboxTexture && (_skyboxTexture->isLoaded() || _skyboxTexture->isFailed())); + qDebug() << "------> " << skyboxLoadedOrFailed; + visuallyReady = (!_skyboxTextureURL.isEmpty() || skyboxLoadedOrFailed); + } + + entity->setVisuallyReady(visuallyReady); } void ZoneEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 47ae8de9ad..490f9b9e6b 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -305,6 +305,7 @@ public: void setDynamic(bool value); virtual bool shouldBePhysical() const { return false; } + bool isVisuallyReady() const { return _visuallyReady; } bool getLocked() const; void setLocked(bool value); @@ -527,6 +528,7 @@ public: void removeCloneID(const QUuid& cloneID); const QVector getCloneIDs() const; void setCloneIDs(const QVector& cloneIDs); + void setVisuallyReady(bool visuallyReady) { _visuallyReady = visuallyReady; } signals: void requestRenderUpdate(); @@ -639,6 +641,7 @@ protected: EntityTreeElementPointer _element; // set by EntityTreeElement void* _physicsInfo { nullptr }; // set by EntitySimulation bool _simulated { false }; // set by EntitySimulation + bool _visuallyReady { true }; bool addActionInternal(EntitySimulationPointer simulation, EntityDynamicPointer action); bool removeActionInternal(const QUuid& actionID, EntitySimulationPointer simulation = nullptr); diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 5d5344c9c8..774559a628 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -40,6 +40,7 @@ ModelEntityItem::ModelEntityItem(const EntityItemID& entityItemID) : EntityItem( _type = EntityTypes::Model; _lastKnownCurrentFrame = -1; _color[0] = _color[1] = _color[2] = 0; + _visuallyReady = false; } const QString ModelEntityItem::getTextures() const { diff --git a/libraries/entities/src/ZoneEntityItem.cpp b/libraries/entities/src/ZoneEntityItem.cpp index f2550e5d3c..58d5ba79c9 100644 --- a/libraries/entities/src/ZoneEntityItem.cpp +++ b/libraries/entities/src/ZoneEntityItem.cpp @@ -42,6 +42,7 @@ ZoneEntityItem::ZoneEntityItem(const EntityItemID& entityItemID) : EntityItem(en _shapeType = DEFAULT_SHAPE_TYPE; _compoundShapeURL = DEFAULT_COMPOUND_SHAPE_URL; + _visuallyReady = false; } EntityItemProperties ZoneEntityItem::getProperties(EntityPropertyFlags desiredProperties) const { diff --git a/scripts/system/interstitialPage.js b/scripts/system/interstitialPage.js index 1507c7bd9a..a5e5e7c0a2 100644 --- a/scripts/system/interstitialPage.js +++ b/scripts/system/interstitialPage.js @@ -32,6 +32,7 @@ var BUTTON_PROPERTIES = { text: "Interstitial" }; + var tablet = null; var button = null; @@ -336,11 +337,12 @@ Overlays.editOverlay(loadingBarPlacard, properties); Overlays.editOverlay(loadingBarProgress, loadingBarProperties); - if (physicsEnabled) { + if (physicsEnabled && !HMD.active) { toolbar.writeProperty("visible", true); - resetValues(); } + resetValues(); + Camera.mode = "first person"; } @@ -356,7 +358,13 @@ Overlays.editOverlay(anchorOverlay, { localPosition: localPosition }); } + + Window.interstitialStatusChanged.connect(function(interstitialMode) { + print("------> insterstitial mode changed " + interstitialMode + " <------"); + }); + function update() { + var downloadInfo = GlobalServices.getDownloadInfo(); var physicsEnabled = Window.isPhysicsEnabled(); var thisInterval = Date.now(); var deltaTime = (thisInterval - lastInterval); @@ -365,7 +373,7 @@ var domainLoadingProgressPercentage = Window.domainLoadingProgress(); var progress = MAX_X_SIZE * domainLoadingProgressPercentage; - print(progress); + //print(progress); if (progress >= target) { target = progress; } @@ -383,6 +391,7 @@ }; Overlays.editOverlay(loadingBarProgress, properties); + print(JSON.stringify(downloadInfo)); if ((physicsEnabled && (currentProgress >= (MAX_X_SIZE - EPSILON)))) { updateOverlays((physicsEnabled || connectionToDomainFailed)); endAudio(); @@ -431,7 +440,9 @@ renderViewTask.getConfig("LightingModel")["enableAmbientLight"] = true; renderViewTask.getConfig("LightingModel")["enableDirectionalLight"] = true; renderViewTask.getConfig("LightingModel")["enablePointLight"] = true; - toolbar.writeProperty("visible", true); + if (!HMD.active) { + toolbar.writeProperty("visible", true); + } } Script.scriptEnding.connect(cleanup); From 2bec8678639e2aff14f83063be6e2154c34ee983 Mon Sep 17 00:00:00 2001 From: amantley Date: Fri, 24 Aug 2018 16:29:08 -0700 Subject: [PATCH 106/545] added the sanity check to see if the shoulders have flipped --- interface/src/avatar/MyAvatar.cpp | 19 ++++++++++++++++--- interface/src/avatar/MyAvatar.h | 2 +- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index a1e30144ee..ae02eacf75 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -458,9 +458,11 @@ void MyAvatar::update(float deltaTime) { glm::vec3 handHipAzimuthSensorSpace = transformVectorFast(worldToSensorMat, glm::vec3(handHipAzimuthWorldSpace.x, 0.0f, handHipAzimuthWorldSpace.z)); glm::vec2 normedHandHip = glm::normalize(glm::vec2(handHipAzimuthSensorSpace.x, handHipAzimuthSensorSpace.z)); glm::vec2 headFacingPlusHandHipAzimuthMix = lerp(normedHandHip, _headControllerFacing, 0.5f); - //qCDebug(interfaceapp) << "the hand hip azimuth " << normedHandHip << "the head look at" << _headControllerFacing; + // if head facing dot mid point hands facing is close to -1 and the hands midpoint is close to -1 you then flip + + // qCDebug(interfaceapp) << "the hand hip azimuth " << normedHandHip << "the head look at" << _headControllerFacing; _headControllerFacingMovingAverage = lerp(_headControllerFacingMovingAverage, headFacingPlusHandHipAzimuthMix, tau); - qCDebug(interfaceapp) << "the hand hip azimuth average " << _headControllerFacingMovingAverage; + // qCDebug(interfaceapp) << "the hand hip azimuth average " << _headControllerFacingMovingAverage; if (_smoothOrientationTimer < SMOOTH_TIME_ORIENTATION) { _rotationChanged = usecTimestampNow(); @@ -831,11 +833,22 @@ void MyAvatar::computeHandAzimuth() { // qCDebug(interfaceapp) << "the right hand in avatar space" << rightHandRigSpace; if (leftHandPoseAvatarSpace.isValid() && rightHandPoseAvatarSpace.isValid()) { + vec2 oldAzimuthReading = _hipToHandController; _hipToHandController = lerp(glm::normalize(glm::vec2(rightHandPoseAvatarSpace.translation.x, rightHandPoseAvatarSpace.translation.z)), glm::normalize(glm::vec2(leftHandPoseAvatarSpace.translation.x, leftHandPoseAvatarSpace.translation.z)), 0.5f); + + //if they are 180 apart + float cosForwardAngle = glm::dot(_hipToHandController, oldAzimuthReading); + float cosBackwardAngle = glm::dot(_hipToHandController, -oldAzimuthReading); + if (cosBackwardAngle > cosForwardAngle) { + // this means we have lost continuity with the current chest position + _hipToHandController = -_hipToHandController; + } + + //need to use easing function here. //var rotateAngle = ((Math.cos((leftRightMidpoint / 180.0) * Math.PI) + 2.0) / 3.0) * leftRightMidpoint; } else { - _hipToHandController = glm::vec2(0.0f, 1.0f); + // _hipToHandController = glm::vec2(0.0f, -1.0f); } } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 177b453267..ea5059bf39 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -1663,7 +1663,7 @@ private: glm::vec2 _headControllerFacingMovingAverage { 0.0f, 0.0f }; // facing vector in xz plane (sensor space) glm::quat _averageHeadRotation { 0.0f, 0.0f, 0.0f, 1.0f }; - glm::vec2 _hipToHandController; // spine2 facing vector in xz plane (avatar space) + glm::vec2 _hipToHandController { 0.0f, -1.0f }; // spine2 facing vector in xz plane (avatar space) float _currentStandingHeight { 0.0f }; bool _resetMode { true }; From 294fe51fdebd5dd5f21f5b6d084d2ec3599f77aa Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 24 Aug 2018 16:48:23 -0700 Subject: [PATCH 107/545] Trying to simplify the LOD culling test --- interface/src/Application.cpp | 2 +- interface/src/LODManager.cpp | 6 ++++++ interface/src/LODManager.h | 4 ++++ libraries/octree/src/OctreeUtils.cpp | 8 ++++++-- libraries/octree/src/OctreeUtils.h | 1 + libraries/render/src/render/Args.h | 5 +++++ scripts/developer/utilities/render/lod.qml | 16 +++++++++++++++- tests-manual/render-perf/src/main.cpp | 2 +- 8 files changed, 39 insertions(+), 5 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e290531471..817c6b1e43 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5987,7 +5987,7 @@ void Application::updateRenderArgs(float deltaTime) { _viewFrustum.calculate(); } appRenderArgs._renderArgs = RenderArgs(_gpuContext, lodManager->getOctreeSizeScale(), - lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, + lodManager->getBoundaryLevelAdjust(), lodManager->getSolidAngleHalfTan(), RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); appRenderArgs._renderArgs._scene = getMain3DScene(); diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index 4f90dee2e5..c46933b2fc 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -319,3 +319,9 @@ float LODManager::getWorldDetailQuality() const { } return HIGH; } + + +float LODManager::getSolidAngleHalfTan() const { + return getPerspectiveAccuracyAngleTan(_octreeSizeScale, _boundaryLevelAdjust); +} + diff --git a/interface/src/LODManager.h b/interface/src/LODManager.h index de026274ad..2ba933f91d 100644 --- a/interface/src/LODManager.h +++ b/interface/src/LODManager.h @@ -69,6 +69,8 @@ class LODManager : public QObject, public Dependency { Q_PROPERTY(float worldDetailQuality READ getWorldDetailQuality WRITE setWorldDetailQuality NOTIFY worldDetailQualityChanged) + Q_PROPERTY(float solidAngleHalfTan READ getSolidAngleHalfTan) + public: /**jsdoc @@ -184,6 +186,8 @@ public: void setWorldDetailQuality(float quality); float getWorldDetailQuality() const; + float getSolidAngleHalfTan() const; + signals: /**jsdoc diff --git a/libraries/octree/src/OctreeUtils.cpp b/libraries/octree/src/OctreeUtils.cpp index 8eaf22e198..be8c194a95 100644 --- a/libraries/octree/src/OctreeUtils.cpp +++ b/libraries/octree/src/OctreeUtils.cpp @@ -64,10 +64,14 @@ float boundaryDistanceForRenderLevel(unsigned int renderLevel, float voxelSizeSc return voxelSizeScale / powf(2.0f, renderLevel); } -float getPerspectiveAccuracyAngle(float octreeSizeScale, int boundaryLevelAdjust) { +float getPerspectiveAccuracyAngleTan(float octreeSizeScale, int boundaryLevelAdjust) { const float maxScale = (float)TREE_SCALE; float visibleDistanceAtMaxScale = boundaryDistanceForRenderLevel(boundaryLevelAdjust, octreeSizeScale) / OCTREE_TO_MESH_RATIO; - return atan(maxScale / visibleDistanceAtMaxScale); + return (maxScale / visibleDistanceAtMaxScale); +} + +float getPerspectiveAccuracyAngle(float octreeSizeScale, int boundaryLevelAdjust) { + return atan(getPerspectiveAccuracyAngleTan(octreeSizeScale, boundaryLevelAdjust)); } float getOrthographicAccuracySize(float octreeSizeScale, int boundaryLevelAdjust) { diff --git a/libraries/octree/src/OctreeUtils.h b/libraries/octree/src/OctreeUtils.h index dff56cad64..4539a54dc3 100644 --- a/libraries/octree/src/OctreeUtils.h +++ b/libraries/octree/src/OctreeUtils.h @@ -29,6 +29,7 @@ float calculateRenderAccuracy(const glm::vec3& position, float boundaryDistanceForRenderLevel(unsigned int renderLevel, float voxelSizeScale); +float getPerspectiveAccuracyAngleTan(float octreeSizeScale, int boundaryLevelAdjust); float getPerspectiveAccuracyAngle(float octreeSizeScale, int boundaryLevelAdjust); float getOrthographicAccuracySize(float octreeSizeScale, int boundaryLevelAdjust); diff --git a/libraries/render/src/render/Args.h b/libraries/render/src/render/Args.h index 627d4f17b2..a46b914826 100644 --- a/libraries/render/src/render/Args.h +++ b/libraries/render/src/render/Args.h @@ -73,12 +73,14 @@ namespace render { Args(const gpu::ContextPointer& context, float sizeScale = 1.0f, int boundaryLevelAdjust = 0, + float solidAngleHalfTan = 0.1f, RenderMode renderMode = DEFAULT_RENDER_MODE, DisplayMode displayMode = MONO, DebugFlags debugFlags = RENDER_DEBUG_NONE, gpu::Batch* batch = nullptr) : _context(context), _sizeScale(sizeScale), + _solidAngleHalfTan(solidAngleHalfTan), _boundaryLevelAdjust(boundaryLevelAdjust), _renderMode(renderMode), _displayMode(displayMode), @@ -105,8 +107,11 @@ namespace render { std::stack _viewFrustums; glm::ivec4 _viewport { 0.0f, 0.0f, 1.0f, 1.0f }; glm::vec3 _boomOffset { 0.0f, 0.0f, 1.0f }; + float _sizeScale { 1.0f }; int _boundaryLevelAdjust { 0 }; + float _solidAngleHalfTan{ 0.1f }; + RenderMode _renderMode { DEFAULT_RENDER_MODE }; DisplayMode _displayMode { MONO }; DebugFlags _debugFlags { RENDER_DEBUG_NONE }; diff --git a/scripts/developer/utilities/render/lod.qml b/scripts/developer/utilities/render/lod.qml index 452d5c7930..688cef142f 100644 --- a/scripts/developer/utilities/render/lod.qml +++ b/scripts/developer/utilities/render/lod.qml @@ -158,7 +158,21 @@ Item { color: "#9999FF" } ] - } + } + PlotPerf { + title: "Solid Angle Half Tan" + height: parent.evalEvenHeight() + object: LODManager + valueScale: 1.0 + valueUnit: "" + plots: [ + { + prop: "solidAngleHalfTan", + label: "SAHT", + color: "#9999FF" + } + ] + } Separator { id: bottomLine } diff --git a/tests-manual/render-perf/src/main.cpp b/tests-manual/render-perf/src/main.cpp index 9238e0dc1c..c9724ea352 100644 --- a/tests-manual/render-perf/src/main.cpp +++ b/tests-manual/render-perf/src/main.cpp @@ -659,7 +659,7 @@ private: update(); _initContext.makeCurrent(); - RenderArgs renderArgs(_renderThread._gpuContext, DEFAULT_OCTREE_SIZE_SCALE, 0, RenderArgs::DEFAULT_RENDER_MODE, + RenderArgs renderArgs(_renderThread._gpuContext, DEFAULT_OCTREE_SIZE_SCALE, 0, getPerspectiveAccuracyAngleTan(DEFAULT_OCTREE_SIZE_SCALE, 0), RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); QSize windowSize = _size; From bf839ca2912b20f7a080be62c1786c4fda47a90d Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Fri, 24 Aug 2018 16:53:38 -0700 Subject: [PATCH 108/545] Handle _unfilteredHandlers first upon processing datagrams --- libraries/networking/src/udt/Socket.cpp | 41 +++++++++++++++---------- libraries/networking/src/udt/Socket.h | 4 +-- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/libraries/networking/src/udt/Socket.cpp b/libraries/networking/src/udt/Socket.cpp index 5b64cc0716..162b045a6e 100644 --- a/libraries/networking/src/udt/Socket.cpp +++ b/libraries/networking/src/udt/Socket.cpp @@ -344,7 +344,7 @@ void Socket::readPendingDatagrams() { continue; } - _incomingDatagrams.push({ senderAddress, senderPort, packetSizeWithHeader, + _incomingDatagrams.push_back({ senderAddress, senderPort, packetSizeWithHeader, std::move(buffer), receiveTime }); ++packetsRead; @@ -361,6 +361,28 @@ void Socket::processPendingDatagrams(int) { // setup a HifiSockAddr to read into HifiSockAddr senderSockAddr; + // Process unfiltered packets first. + for (auto datagramIter = _incomingDatagrams.begin(); datagramIter != _incomingDatagrams.end(); ++datagramIter) { + senderSockAddr.setAddress(datagramIter->_senderAddress); + senderSockAddr.setPort(datagramIter->_senderPort); + auto it = _unfilteredHandlers.find(senderSockAddr); + if (it != _unfilteredHandlers.end()) { + // we have a registered unfiltered handler for this HifiSockAddr (eg. STUN packet) - call that and return + if (it->second) { + auto basePacket = BasePacket::fromReceivedPacket(std::move(datagramIter->_datagram), + datagramIter->_datagramLength, + senderSockAddr); + basePacket->setReceiveTime(datagramIter->_receiveTime); + it->second(std::move(basePacket)); + } + + datagramIter = _incomingDatagrams.erase(datagramIter); + if (datagramIter == _incomingDatagrams.end()) { + break; + } + } + } + while (!_incomingDatagrams.empty()) { auto& datagram = _incomingDatagrams.front(); senderSockAddr.setAddress(datagram._senderAddress); @@ -370,19 +392,6 @@ void Socket::processPendingDatagrams(int) { auto it = _unfilteredHandlers.find(senderSockAddr); - if (it != _unfilteredHandlers.end()) { - // we have a registered unfiltered handler for this HifiSockAddr (eg. STUN packet) - call that and return - if (it->second) { - auto basePacket = BasePacket::fromReceivedPacket(std::move(datagram._datagram), datagramSize, - senderSockAddr); - basePacket->setReceiveTime(datagram._receiveTime); - it->second(std::move(basePacket)); - } - - _incomingDatagrams.pop(); - continue; - } - // we're reading a packet so re-start the readyRead backup timer _readyReadBackupTimer->start(); @@ -427,7 +436,7 @@ void Socket::processPendingDatagrams(int) { qCDebug(networking) << "Can't process packet: version" << (unsigned int)NLPacket::versionInHeader(*packet) << ", type" << NLPacket::typeInHeader(*packet); #endif - _incomingDatagrams.pop(); + _incomingDatagrams.pop_front(); continue; } } @@ -444,7 +453,7 @@ void Socket::processPendingDatagrams(int) { } } - _incomingDatagrams.pop(); + _incomingDatagrams.pop_front(); } } diff --git a/libraries/networking/src/udt/Socket.h b/libraries/networking/src/udt/Socket.h index 078863663f..ef4a457116 100644 --- a/libraries/networking/src/udt/Socket.h +++ b/libraries/networking/src/udt/Socket.h @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include @@ -156,7 +156,7 @@ private: p_high_resolution_clock::time_point _receiveTime; }; - std::queue _incomingDatagrams; + std::list _incomingDatagrams; int _maxDatagramsRead { 0 }; friend UDTTest; From 92acaade2b736eab9c711d1f3586d90107f097e8 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Fri, 24 Aug 2018 17:13:57 -0700 Subject: [PATCH 109/545] trying to fix problems --- interface/src/octree/SafeLanding.cpp | 2 +- .../entities-renderer/src/RenderableModelEntityItem.cpp | 5 +---- libraries/entities-renderer/src/RenderableModelEntityItem.h | 2 -- libraries/entities-renderer/src/RenderableZoneEntityItem.cpp | 4 ++-- 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/interface/src/octree/SafeLanding.cpp b/interface/src/octree/SafeLanding.cpp index bdaaa58fcc..262f0b30c2 100644 --- a/interface/src/octree/SafeLanding.cpp +++ b/interface/src/octree/SafeLanding.cpp @@ -174,7 +174,7 @@ bool SafeLanding::entitiesRenderReady() { for (auto entityMapIter = _trackedEntitiesRenderStatus.begin(); entityMapIter != _trackedEntitiesRenderStatus.end(); ++entityMapIter) { auto entity = entityMapIter->second; bool visuallyReady = entity->isVisuallyReady(); - qDebug() << "is entityType: " << EntityTypes::getEntityTypeName(entity->getType()) << " " << visuallyReady; + qDebug() << "is entityType: " << EntityTypes::getEntityTypeName(entity->getType()) << " " << visuallyReady << " " << entityMapIter->first; if (visuallyReady) { entityMapIter = _trackedEntitiesRenderStatus.erase(entityMapIter); if (entityMapIter == _trackedEntitiesRenderStatus.end()) { diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index c3cc634236..ec46a37a1c 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -1455,12 +1455,9 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce } emit requestRenderUpdate(); } -} - -void ModelEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { withWriteLock([&] { - bool visuallyReady = (_prevModelLoaded && _texturesLoaded); + bool visuallyReady = ((_prevModelLoaded && _texturesLoaded) || model->getURL().isEmpty()); entity->setVisuallyReady(visuallyReady); }); } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index bcf7296456..3540fa1127 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -164,8 +164,6 @@ protected: virtual void doRender(RenderArgs* args) override; virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override; - virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override; - render::hifi::Tag getTagMask() const override; void setIsVisibleInSecondaryCamera(bool value) override; diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index ba561cd8b2..2f36796f84 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -293,8 +293,8 @@ void ZoneEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scen uint32_t skyboxMode = entity->getSkyboxMode(); if (skyboxMode == COMPONENT_MODE_ENABLED) { bool skyboxLoadedOrFailed = (_skyboxTexture && (_skyboxTexture->isLoaded() || _skyboxTexture->isFailed())); - qDebug() << "------> " << skyboxLoadedOrFailed; - visuallyReady = (!_skyboxTextureURL.isEmpty() || skyboxLoadedOrFailed); + qDebug() << entity->getEntityItemID() << "------> " << _skyboxTexture->isFailed() << _skyboxTexture->isLoaded() << _skyboxTextureURL.isEmpty(); + visuallyReady = (_skyboxTextureURL.isEmpty() || skyboxLoadedOrFailed); } entity->setVisuallyReady(visuallyReady); From ab810f45050c0e03011cd384070968fe3b1e53ea Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Fri, 24 Aug 2018 17:33:06 -0700 Subject: [PATCH 110/545] Try reducing use of shared pointers in O(n2) code --- .../src/avatars/AvatarMixerSlave.cpp | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index f347ff1f10..3e9755ed39 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -210,6 +210,7 @@ void AvatarMixerSlave::broadcastAvatarData(const SharedNodePointer& node) { } void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) { + const Node* nodeRaw = node.data(); auto nodeList = DependencyManager::get(); @@ -220,7 +221,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) _stats.nodesBroadcastedTo++; - AvatarMixerClientData* nodeData = reinterpret_cast(node->getLinkedData()); + AvatarMixerClientData* nodeData = reinterpret_cast(nodeRaw->getLinkedData()); nodeData->resetInViewStats(); @@ -260,7 +261,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) bool PALIsOpen = nodeData->getRequestsDomainListData(); // When this is true, the AvatarMixer will send Avatar data to a client about avatars that have ignored them - bool getsAnyIgnored = PALIsOpen && node->getCanKick(); + bool getsAnyIgnored = PALIsOpen && nodeRaw->getCanKick(); if (PALIsOpen) { // Increase minimumBytesPerAvatar if the PAL is open @@ -286,8 +287,8 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // setup list of AvatarData as well as maps to map betweeen the AvatarData and the original nodes - std::vector avatarsToSort; - std::unordered_map avatarDataToNodes; + std::vector avatarsToSort; + std::unordered_map avatarDataToNodes; std::unordered_map avatarEncodeTimes; std::for_each(_begin, _end, [&](const SharedNodePointer& otherNode) { // make sure this is an agent that we have avatar data for before considering it for inclusion @@ -295,7 +296,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) && otherNode->getLinkedData()) { const AvatarMixerClientData* otherNodeData = reinterpret_cast(otherNode->getLinkedData()); - AvatarSharedPointer otherAvatar = otherNodeData->getAvatarSharedPointer(); + AvatarData* otherAvatar = otherNodeData->getAvatarSharedPointer().get(); avatarsToSort.push_back(otherAvatar); avatarDataToNodes[otherAvatar] = otherNode; QUuid id = otherAvatar->getSessionUUID(); @@ -306,7 +307,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) class SortableAvatar: public PrioritySortUtil::Sortable { public: SortableAvatar() = delete; - SortableAvatar(const AvatarSharedPointer& avatar, uint64_t lastEncodeTime) + SortableAvatar(const AvatarData* avatar, uint64_t lastEncodeTime) : _avatar(avatar), _lastEncodeTime(lastEncodeTime) {} glm::vec3 getPosition() const override { return _avatar->getWorldPosition(); } float getRadius() const override { @@ -316,10 +317,10 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) uint64_t getTimestamp() const override { return _lastEncodeTime; } - AvatarSharedPointer getAvatar() const { return _avatar; } + const AvatarData* getAvatar() const { return _avatar; } private: - AvatarSharedPointer _avatar; + const AvatarData* _avatar; uint64_t _lastEncodeTime; }; @@ -332,8 +333,8 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // ignore or sort const AvatarSharedPointer& thisAvatar = nodeData->getAvatarSharedPointer(); - for (const auto& avatar : avatarsToSort) { - if (avatar == thisAvatar) { + for (const auto avatar : avatarsToSort) { + if (avatar == thisAvatar.get()) { // don't echo updates to self continue; } @@ -356,14 +357,14 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // and isn't an avatar that the viewing node has ignored // or that has ignored the viewing node if (!avatarNode->getLinkedData() - || avatarNode->getUUID() == node->getUUID() - || (node->isIgnoringNodeWithID(avatarNode->getUUID()) && !PALIsOpen) - || (avatarNode->isIgnoringNodeWithID(node->getUUID()) && !getsAnyIgnored)) { + || avatarNode->getUUID() == nodeRaw->getUUID() + || (nodeRaw->isIgnoringNodeWithID(avatarNode->getUUID()) && !PALIsOpen) + || (avatarNode->isIgnoringNodeWithID(nodeRaw->getUUID()) && !getsAnyIgnored)) { shouldIgnore = true; } else { // Check to see if the space bubble is enabled // Don't bother with these checks if the other avatar has their bubble enabled and we're gettingAnyIgnored - if (node->isIgnoreRadiusEnabled() || (avatarNode->isIgnoreRadiusEnabled() && !getsAnyIgnored)) { + if (nodeRaw->isIgnoreRadiusEnabled() || (avatarNode->isIgnoreRadiusEnabled() && !getsAnyIgnored)) { float sensorToWorldScale = avatarNodeData->getAvatarSharedPointer()->getSensorToWorldScale(); // Define the scale of the box for the current other node glm::vec3 otherNodeBoxScale = (avatarNodeData->getPosition() - avatarNodeData->getGlobalBoundingBoxCorner()) * 2.0f * sensorToWorldScale; @@ -430,7 +431,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) int remainingAvatars = (int)sortedAvatars.size(); auto traitsPacketList = NLPacketList::create(PacketType::BulkAvatarTraits, QByteArray(), true, true); while (!sortedAvatars.empty()) { - const auto avatarData = sortedAvatars.top().getAvatar(); + const AvatarData* avatarData = sortedAvatars.top().getAvatar(); sortedAvatars.pop(); remainingAvatars--; @@ -565,7 +566,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) _stats.numBytesSent += numAvatarDataBytes; // send the avatar data PacketList - nodeList->sendPacketList(std::move(avatarPacketList), *node); + nodeList->sendPacketList(std::move(avatarPacketList), *nodeRaw); // record the bytes sent for other avatar data in the AvatarMixerClientData nodeData->recordSentAvatarData(numAvatarDataBytes); @@ -575,7 +576,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) if (traitsPacketList->getNumPackets() >= 1) { // send the traits packet list - nodeList->sendPacketList(std::move(traitsPacketList), *node); + nodeList->sendPacketList(std::move(traitsPacketList), *nodeRaw); } // record the number of avatars held back this frame From 861d1e26a99be1f9b4839cb25f6ff2fabeac24da Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Fri, 24 Aug 2018 18:02:28 -0700 Subject: [PATCH 111/545] Remove unused variable --- libraries/networking/src/udt/Socket.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/networking/src/udt/Socket.cpp b/libraries/networking/src/udt/Socket.cpp index 162b045a6e..56b7521d7a 100644 --- a/libraries/networking/src/udt/Socket.cpp +++ b/libraries/networking/src/udt/Socket.cpp @@ -390,8 +390,6 @@ void Socket::processPendingDatagrams(int) { int datagramSize = datagram._datagramLength; auto receiveTime = datagram._receiveTime; - auto it = _unfilteredHandlers.find(senderSockAddr); - // we're reading a packet so re-start the readyRead backup timer _readyReadBackupTimer->start(); From e4293d9ad57705cfb778737c337ff8018a9a8b13 Mon Sep 17 00:00:00 2001 From: danteruiz Date: Sun, 26 Aug 2018 21:50:01 -0700 Subject: [PATCH 112/545] fixing some entity visual problems --- interface/src/Application.cpp | 1 - interface/src/octree/SafeLanding.cpp | 9 +++++--- .../src/RenderableModelEntityItem.cpp | 21 ++++++++++++------- .../src/RenderableZoneEntityItem.cpp | 7 ++++--- scripts/system/interstitialPage.js | 13 ++++-------- 5 files changed, 28 insertions(+), 23 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 092fb51a2a..37e31650a0 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5544,7 +5544,6 @@ void Application::update(float deltaTime) { // for nearby entities before starting bullet up. quint64 now = usecTimestampNow(); bool renderReady = _octreeProcessor.isEntitiesRenderReady(); - qDebug() << "--> render ready: " << renderReady; if (isServerlessMode() || (_octreeProcessor.isLoadSequenceComplete() && renderReady)) { // we've received a new full-scene octree stats packet, or it's been long enough to try again anyway _lastPhysicsCheckTime = now; diff --git a/interface/src/octree/SafeLanding.cpp b/interface/src/octree/SafeLanding.cpp index 262f0b30c2..8d36b3fcb0 100644 --- a/interface/src/octree/SafeLanding.cpp +++ b/interface/src/octree/SafeLanding.cpp @@ -13,6 +13,7 @@ #include "EntityTreeRenderer.h" #include "ModelEntityItem.h" #include "InterfaceLogging.h" +#include "Application.h" const int SafeLanding::SEQUENCE_MODULO = std::numeric_limits::max() + 1; @@ -129,7 +130,7 @@ bool SafeLanding::isLoadSequenceComplete() { float SafeLanding::loadingProgressPercentage() { Locker lock(_lock); if (_maxTrackedEntityCount > 0) { - float trackedEntityCount = (float)_trackedEntities.size(); + float trackedEntityCount = (float)_trackedEntitiesRenderStatus.size(); return ((_maxTrackedEntityCount - trackedEntityCount) / _maxTrackedEntityCount); } @@ -170,16 +171,18 @@ bool SafeLanding::isEntityPhysicsComplete() { bool SafeLanding::entitiesRenderReady() { Locker lock(_lock); - + auto entityTree = qApp->getEntities(); for (auto entityMapIter = _trackedEntitiesRenderStatus.begin(); entityMapIter != _trackedEntitiesRenderStatus.end(); ++entityMapIter) { auto entity = entityMapIter->second; bool visuallyReady = entity->isVisuallyReady(); qDebug() << "is entityType: " << EntityTypes::getEntityTypeName(entity->getType()) << " " << visuallyReady << " " << entityMapIter->first; - if (visuallyReady) { + if (visuallyReady || !entityTree->renderableForEntityId(entityMapIter->first)) { entityMapIter = _trackedEntitiesRenderStatus.erase(entityMapIter); if (entityMapIter == _trackedEntitiesRenderStatus.end()) { break; } + } else { + entity->requestRenderUpdate(); } } qDebug() << "list size: -> " << _trackedEntitiesRenderStatus.size(); diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index ec46a37a1c..baa20a0583 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -1297,9 +1297,21 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce } }); - // Check for removal ModelPointer model; withReadLock([&] { model = _model; }); + + withWriteLock([&] { + bool visuallyReady = true; + if (_hasModel) { + if (model && _didLastVisualGeometryRequestSucceed) { + visuallyReady = (_prevModelLoaded && _texturesLoaded); + // qDebug() << visuallyReady; + } + } + entity->setVisuallyReady(visuallyReady); + }); + + // Check for removal if (!_hasModel) { if (model) { model->removeFromScene(scene, transaction); @@ -1445,7 +1457,7 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce if (!jointsMapped()) { mapJoints(entity, model->getJointNames()); //else the joint have been mapped before but we have a new animation to load - } else if (_animation && (_animation->getURL().toString() != entity->getAnimationURL())) { + } else if (_animation && (_animation->getURL().toString() != entity->getAnimationURL())) { _animation = DependencyManager::get()->getAnimation(entity->getAnimationURL()); _jointMappingCompleted = false; mapJoints(entity, model->getJointNames()); @@ -1455,11 +1467,6 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce } emit requestRenderUpdate(); } - - withWriteLock([&] { - bool visuallyReady = ((_prevModelLoaded && _texturesLoaded) || model->getURL().isEmpty()); - entity->setVisuallyReady(visuallyReady); - }); } void ModelEntityRenderer::setIsVisibleInSecondaryCamera(bool value) { diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index 2f36796f84..cf452c9cf7 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -291,11 +291,12 @@ void ZoneEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scen bool visuallyReady = true; uint32_t skyboxMode = entity->getSkyboxMode(); - if (skyboxMode == COMPONENT_MODE_ENABLED) { + if (skyboxMode == COMPONENT_MODE_ENABLED && !_skyboxTextureURL.isEmpty()) { bool skyboxLoadedOrFailed = (_skyboxTexture && (_skyboxTexture->isLoaded() || _skyboxTexture->isFailed())); - qDebug() << entity->getEntityItemID() << "------> " << _skyboxTexture->isFailed() << _skyboxTexture->isLoaded() << _skyboxTextureURL.isEmpty(); - visuallyReady = (_skyboxTextureURL.isEmpty() || skyboxLoadedOrFailed); + + visuallyReady = skyboxLoadedOrFailed; } + entity->setVisuallyReady(visuallyReady); if (bloomChanged) { diff --git a/scripts/system/interstitialPage.js b/scripts/system/interstitialPage.js index a5e5e7c0a2..cf06e222c9 100644 --- a/scripts/system/interstitialPage.js +++ b/scripts/system/interstitialPage.js @@ -223,7 +223,7 @@ function startInterstitialPage() { if (timer === null) { - updateOverlays(Window.isPhysicsEnabled()); + updateOverlays(false); startAudio(); target = 0; currentProgress = 0.1; @@ -364,7 +364,6 @@ }); function update() { - var downloadInfo = GlobalServices.getDownloadInfo(); var physicsEnabled = Window.isPhysicsEnabled(); var thisInterval = Date.now(); var deltaTime = (thisInterval - lastInterval); @@ -373,14 +372,11 @@ var domainLoadingProgressPercentage = Window.domainLoadingProgress(); var progress = MAX_X_SIZE * domainLoadingProgressPercentage; - //print(progress); - if (progress >= target) { + print(progress); + //if (progress >= target) { target = progress; - } + //} - if (physicsEnabled && target < MAX_X_SIZE) { - target = MAX_X_SIZE; - } currentProgress = lerp(currentProgress, target, 0.2); var properties = { localPosition: { x: (1.85 - (currentProgress / 2) - (-0.029 * (currentProgress / MAX_X_SIZE))), y: -0.935, z: 0.0 }, @@ -391,7 +387,6 @@ }; Overlays.editOverlay(loadingBarProgress, properties); - print(JSON.stringify(downloadInfo)); if ((physicsEnabled && (currentProgress >= (MAX_X_SIZE - EPSILON)))) { updateOverlays((physicsEnabled || connectionToDomainFailed)); endAudio(); From d97d655148ab70514241f31c6de19ea691d227c1 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Sun, 26 Aug 2018 23:17:29 -0700 Subject: [PATCH 113/545] USing a simpler halfTan test for culling --- interface/src/LODManager.cpp | 13 +++++++++++-- interface/src/LODManager.h | 2 ++ libraries/octree/src/OctreeUtils.cpp | 6 ------ libraries/octree/src/OctreeUtils.h | 2 -- libraries/render-utils/src/RenderShadowTask.cpp | 4 ++-- libraries/render/src/render/CullTask.cpp | 2 +- libraries/render/src/render/CullTask.h | 6 +++--- scripts/developer/utilities/render/lod.qml | 9 +++++---- 8 files changed, 24 insertions(+), 20 deletions(-) diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index c46933b2fc..cd692bccf0 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -237,8 +237,14 @@ QString LODManager::getLODFeedbackText() { bool LODManager::shouldRender(const RenderArgs* args, const AABox& bounds) { // FIXME - eventually we want to use the render accuracy as an indicator for the level of detail // to use in rendering. - float renderAccuracy = calculateRenderAccuracy(args->getViewFrustum().getPosition(), bounds, args->_sizeScale, args->_boundaryLevelAdjust); - return (renderAccuracy > 0.0f); + // float renderAccuracy = calculateRenderAccuracy(args->getViewFrustum().getPosition(), bounds, args->_sizeScale, args->_boundaryLevelAdjust); + // return (renderAccuracy > 0.0f); + + auto pos = args->getViewFrustum().getPosition() - bounds.calcCenter(); + auto dim = bounds.getDimensions(); + auto halfTanSq = 0.25f * glm::dot(dim, dim) / glm::dot(pos, pos); + return (halfTanSq >= args->_solidAngleHalfTan * args->_solidAngleHalfTan); + }; void LODManager::setOctreeSizeScale(float sizeScale) { @@ -325,3 +331,6 @@ float LODManager::getSolidAngleHalfTan() const { return getPerspectiveAccuracyAngleTan(_octreeSizeScale, _boundaryLevelAdjust); } +float LODManager::getSolidAngle() const { + return glm::degrees(2.0 * atan(getSolidAngleHalfTan())); +} diff --git a/interface/src/LODManager.h b/interface/src/LODManager.h index 2ba933f91d..340292c579 100644 --- a/interface/src/LODManager.h +++ b/interface/src/LODManager.h @@ -70,6 +70,7 @@ class LODManager : public QObject, public Dependency { Q_PROPERTY(float worldDetailQuality READ getWorldDetailQuality WRITE setWorldDetailQuality NOTIFY worldDetailQualityChanged) Q_PROPERTY(float solidAngleHalfTan READ getSolidAngleHalfTan) + Q_PROPERTY(float solidAngle READ getSolidAngle) public: @@ -187,6 +188,7 @@ public: float getWorldDetailQuality() const; float getSolidAngleHalfTan() const; + float getSolidAngle() const; signals: diff --git a/libraries/octree/src/OctreeUtils.cpp b/libraries/octree/src/OctreeUtils.cpp index be8c194a95..7ed9c2ed3c 100644 --- a/libraries/octree/src/OctreeUtils.cpp +++ b/libraries/octree/src/OctreeUtils.cpp @@ -79,9 +79,3 @@ float getOrthographicAccuracySize(float octreeSizeScale, int boundaryLevelAdjust const float smallestSize = 0.01f; return (smallestSize * MAX_VISIBILITY_DISTANCE_FOR_UNIT_ELEMENT) / boundaryDistanceForRenderLevel(boundaryLevelAdjust, octreeSizeScale); } - -bool isAngularSizeBigEnough(glm::vec3 position, const AACube& cube, float lodScaleFactor, float minDiameter) { - float distance = glm::distance(cube.calcCenter(), position) + MIN_VISIBLE_DISTANCE; - float angularDiameter = cube.getScale() / distance; - return angularDiameter > minDiameter * lodScaleFactor; -} diff --git a/libraries/octree/src/OctreeUtils.h b/libraries/octree/src/OctreeUtils.h index 4539a54dc3..eedbfe8bda 100644 --- a/libraries/octree/src/OctreeUtils.h +++ b/libraries/octree/src/OctreeUtils.h @@ -39,6 +39,4 @@ const float MIN_ELEMENT_ANGULAR_DIAMETER = 0.0043301f; // radians const float MIN_ENTITY_ANGULAR_DIAMETER = MIN_ELEMENT_ANGULAR_DIAMETER * SQRT_THREE; const float MIN_VISIBLE_DISTANCE = 0.0001f; // helps avoid divide-by-zero check -bool isAngularSizeBigEnough(glm::vec3 position, const AACube& cube, float lodScaleFactor, float minDiameter); - #endif // hifi_OctreeUtils_h diff --git a/libraries/render-utils/src/RenderShadowTask.cpp b/libraries/render-utils/src/RenderShadowTask.cpp index b073037e32..137ee07c96 100644 --- a/libraries/render-utils/src/RenderShadowTask.cpp +++ b/libraries/render-utils/src/RenderShadowTask.cpp @@ -62,8 +62,8 @@ void RenderShadowTask::build(JobModel& task, const render::Varying& input, rende const auto fetchInput = FetchSpatialTree::Inputs(shadowCasterReceiverFilter, queryResolution).asVarying(); const auto shadowSelection = task.addJob("FetchShadowTree", fetchInput); - const auto selectionInputs = FetchSpatialSelection::Inputs(shadowSelection, shadowCasterReceiverFilter).asVarying(); - const auto shadowItems = task.addJob("FetchShadowSelection", selectionInputs); + const auto selectionInputs = FilterSpatialSelection::Inputs(shadowSelection, shadowCasterReceiverFilter).asVarying(); + const auto shadowItems = task.addJob("FilterShadowSelection", selectionInputs); // Cull objects that are not visible in camera view. Hopefully the cull functor only performs LOD culling, not // frustum culling or this will make shadow casters out of the camera frustum disappear. diff --git a/libraries/render/src/render/CullTask.cpp b/libraries/render/src/render/CullTask.cpp index b5f1718f6c..7d03f67d3f 100644 --- a/libraries/render/src/render/CullTask.cpp +++ b/libraries/render/src/render/CullTask.cpp @@ -445,7 +445,7 @@ void ApplyCullFunctorOnItemBounds::run(const RenderContextPointer& renderContext } } -void FetchSpatialSelection::run(const RenderContextPointer& renderContext, +void FilterSpatialSelection::run(const RenderContextPointer& renderContext, const Inputs& inputs, ItemBounds& outItems) { assert(renderContext->args); auto& scene = renderContext->_scene; diff --git a/libraries/render/src/render/CullTask.h b/libraries/render/src/render/CullTask.h index 2ef9e92eaa..99ca7abe6c 100644 --- a/libraries/render/src/render/CullTask.h +++ b/libraries/render/src/render/CullTask.h @@ -147,12 +147,12 @@ namespace render { }; - class FetchSpatialSelection { + class FilterSpatialSelection { public: using Inputs = render::VaryingSet2; - using JobModel = Job::ModelIO; + using JobModel = Job::ModelIO; - FetchSpatialSelection() {} + FilterSpatialSelection() {} void run(const RenderContextPointer& renderContext, const Inputs& inputs, ItemBounds& outItems); }; diff --git a/scripts/developer/utilities/render/lod.qml b/scripts/developer/utilities/render/lod.qml index 688cef142f..c08c089bad 100644 --- a/scripts/developer/utilities/render/lod.qml +++ b/scripts/developer/utilities/render/lod.qml @@ -160,15 +160,16 @@ Item { ] } PlotPerf { - title: "Solid Angle Half Tan" + title: "Solid Angle" height: parent.evalEvenHeight() object: LODManager valueScale: 1.0 - valueUnit: "" + valueUnit: "deg" + //valueNumDigits: 0 plots: [ { - prop: "solidAngleHalfTan", - label: "SAHT", + prop: "solidAngle", + label: "Solid Angle", color: "#9999FF" } ] From 8ede6f1cd09cf2ed33a006fa9629dae134fe0d5f Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Mon, 27 Aug 2018 06:55:52 -0700 Subject: [PATCH 114/545] Fix removing my avatar and code standards --- libraries/avatars/src/AvatarData.cpp | 16 ++++----------- libraries/avatars/src/AvatarHashMap.cpp | 26 ++++++++++++------------- libraries/avatars/src/AvatarHashMap.h | 4 ++-- 3 files changed, 19 insertions(+), 27 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index ddb53f8acb..5e1094276c 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -919,19 +919,11 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { PACKET_READ_CHECK(AvatarGlobalPosition, sizeof(AvatarDataPacket::AvatarGlobalPosition)); auto data = reinterpret_cast(sourceBuffer); - const float SPACE_BETWEEN_AVATARS = 2.0f; - const int RANDOM_RADIUS = 100; - const int AVATARS_PER_ROW = 3; + glm::vec3 offset = glm::vec3(0.0f, 0.0f, 0.0f); - glm::vec3 offset; - - if (false) { - qsrand(static_cast(getID().toByteArray().toInt())); - float xrand = float((qrand() % ((RANDOM_RADIUS + 1) - 10) + 10) / 10.0f); - float yrand = float((qrand() % ((RANDOM_RADIUS + 1) - 10) + 10) / 10.0f); - offset = glm::vec3(xrand, 0.0f, yrand); - } - else { + if (_replicaIndex > 0) { + const float SPACE_BETWEEN_AVATARS = 2.0f; + const int AVATARS_PER_ROW = 3; int row = _replicaIndex % AVATARS_PER_ROW; int col = floor(_replicaIndex / AVATARS_PER_ROW); offset = glm::vec3(row * SPACE_BETWEEN_AVATARS, 0.0f, col * SPACE_BETWEEN_AVATARS); diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index 67cc9f0563..8dfee3551e 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -23,6 +23,9 @@ void AvatarReplicas::addReplica(const QUuid& parentID, AvatarSharedPointer replica) { + if (parentID == QUuid()) { + return; + } if (_replicasMap.find(parentID) == _replicasMap.end()) { std::vector emptyReplicas = std::vector(); _replicasMap.insert(std::pair>(parentID, emptyReplicas)); @@ -144,10 +147,12 @@ void AvatarHashMap::setReplicaCount(int count) { auto avatars = getAvatarIdentifiers(); for (int i = 0; i < avatars.size(); i++) { KillAvatarReason reason = KillAvatarReason::NoReason; - removeAvatar(avatars[i], reason); - auto replicaIDs = _replicas.getReplicaIDs(avatars[i]); - for (auto id : replicaIDs) { - removeAvatar(id, reason); + if (avatars[i] != QUuid()) { + removeAvatar(avatars[i], reason); + auto replicaIDs = _replicas.getReplicaIDs(avatars[i]); + for (auto id : replicaIDs) { + removeAvatar(id, reason); + } } } } @@ -315,7 +320,6 @@ void AvatarHashMap::processBulkAvatarTraits(QSharedPointer mess AvatarTraits::TraitWireSize traitBinarySize; bool skipBinaryTrait = false; - if (AvatarTraits::isSimpleTrait(traitType)) { message->readPrimitive(&traitBinarySize); @@ -325,12 +329,10 @@ void AvatarHashMap::processBulkAvatarTraits(QSharedPointer mess avatar->processTrait(traitType, traitData); _replicas.processTrait(avatarID, traitType, traitData); lastProcessedVersions[traitType] = packetTraitVersion; - } - else { + } else { skipBinaryTrait = true; } - } - else { + } else { AvatarTraits::TraitInstanceID traitInstanceID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); @@ -341,15 +343,13 @@ void AvatarHashMap::processBulkAvatarTraits(QSharedPointer mess if (traitBinarySize == AvatarTraits::DELETED_TRAIT_SIZE) { avatar->processDeletedTraitInstance(traitType, traitInstanceID); _replicas.processDeletedTraitInstance(avatarID, traitType, traitInstanceID); - } - else { + } else { auto traitData = message->read(traitBinarySize); avatar->processTraitInstance(traitType, traitInstanceID, traitData); _replicas.processTraitInstance(avatarID, traitType, traitInstanceID, traitData); } processedInstanceVersion = packetTraitVersion; - } - else { + } else { skipBinaryTrait = true; } } diff --git a/libraries/avatars/src/AvatarHashMap.h b/libraries/avatars/src/AvatarHashMap.h index e4e197a080..0f847b2a61 100644 --- a/libraries/avatars/src/AvatarHashMap.h +++ b/libraries/avatars/src/AvatarHashMap.h @@ -43,7 +43,7 @@ class AvatarReplicas { public: - AvatarReplicas() : _replicaCount(0) {} + AvatarReplicas() {} void addReplica(const QUuid& parentID, AvatarSharedPointer replica); std::vector getReplicaIDs(const QUuid& parentID); void parseDataFromBuffer(const QUuid& parentID, const QByteArray& buffer); @@ -58,7 +58,7 @@ public: private: std::map> _replicasMap; - int _replicaCount; + int _replicaCount { 0 }; }; From 62814deb328201ba6fe3a122514c9fbc5d61a730 Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Mon, 27 Aug 2018 08:34:01 -0700 Subject: [PATCH 115/545] Added read of map_d from MTL files --- libraries/fbx/src/OBJReader.cpp | 31 +++++++++++++++++++++---------- libraries/fbx/src/OBJReader.h | 2 ++ 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/libraries/fbx/src/OBJReader.cpp b/libraries/fbx/src/OBJReader.cpp index caac08f777..501fb72130 100644 --- a/libraries/fbx/src/OBJReader.cpp +++ b/libraries/fbx/src/OBJReader.cpp @@ -263,15 +263,19 @@ void OBJReader::parseMaterialLibrary(QIODevice* device) { default: materials[matName] = currentMaterial; #ifdef WANT_DEBUG - qCDebug(modelformat) << "OBJ Reader Last material illumination model:" << currentMaterial.illuminationModel << - " shininess:" << currentMaterial.shininess << " opacity:" << currentMaterial.opacity << - " diffuse color:" << currentMaterial.diffuseColor << " specular color:" << - currentMaterial.specularColor << " emissive color:" << currentMaterial.emissiveColor << - " diffuse texture:" << currentMaterial.diffuseTextureFilename << " specular texture:" << - currentMaterial.specularTextureFilename << " emissive texture:" << - currentMaterial.emissiveTextureFilename << " bump texture:" << - currentMaterial.bumpTextureFilename; - #endif + qCDebug(modelformat) << + "OBJ Reader Last material illumination model:" << currentMaterial.illuminationModel << + " shininess:" << currentMaterial.shininess << + " opacity:" << currentMaterial.opacity << + " diffuse color:" << currentMaterial.diffuseColor << + " specular color:" << currentMaterial.specularColor << + " emissive color:" << currentMaterial.emissiveColor << + " diffuse texture:" << currentMaterial.diffuseTextureFilename << + " specular texture:" << currentMaterial.specularTextureFilename << + " emissive texture:" << currentMaterial.emissiveTextureFilename << + " bump texture:" << currentMaterial.bumpTextureFilename; + " opacity texture:" << currentMaterial.opacityTextureFilename; +#endif return; } QByteArray token = tokenizer.getDatum(); @@ -289,6 +293,8 @@ void OBJReader::parseMaterialLibrary(QIODevice* device) { currentMaterial.emissiveTextureFilename = ""; currentMaterial.specularTextureFilename = ""; currentMaterial.bumpTextureFilename = ""; + currentMaterial.opacityTextureFilename = ""; + } else if (token == "Ns") { currentMaterial.shininess = tokenizer.getFloat(); } else if (token == "Ni") { @@ -321,7 +327,7 @@ void OBJReader::parseMaterialLibrary(QIODevice* device) { currentMaterial.emissiveColor = tokenizer.getVec3(); } else if (token == "Ks") { currentMaterial.specularColor = tokenizer.getVec3(); - } else if ((token == "map_Kd") || (token == "map_Ke") || (token == "map_Ks") || (token == "map_bump") || (token == "bump")) { + } else if ((token == "map_Kd") || (token == "map_Ke") || (token == "map_Ks") || (token == "map_bump") || (token == "bump") || (token == "map_d")) { const QByteArray textureLine = tokenizer.getLineAsDatum(); QByteArray filename; OBJMaterialTextureOptions textureOptions; @@ -341,6 +347,8 @@ void OBJReader::parseMaterialLibrary(QIODevice* device) { } else if ((token == "map_bump") || (token == "bump")) { currentMaterial.bumpTextureFilename = filename; currentMaterial.bumpTextureOptions = textureOptions; + } else if (token == "map_d") { + currentMaterial.opacityTextureFilename = filename; } } } @@ -900,6 +908,9 @@ FBXGeometry::Pointer OBJReader::readOBJ(QByteArray& model, const QVariantHash& m fbxMaterial.normalTexture.isBumpmap = true; fbxMaterial.bumpMultiplier = objMaterial.bumpTextureOptions.bumpMultiplier; } + if (!objMaterial.opacityTextureFilename.isEmpty()) { + fbxMaterial.opacityTexture.filename = objMaterial.opacityTextureFilename; + } modelMaterial->setEmissive(fbxMaterial.emissiveColor); modelMaterial->setAlbedo(fbxMaterial.diffuseColor); diff --git a/libraries/fbx/src/OBJReader.h b/libraries/fbx/src/OBJReader.h index 13ddc6e21c..e432a3ea51 100644 --- a/libraries/fbx/src/OBJReader.h +++ b/libraries/fbx/src/OBJReader.h @@ -66,6 +66,8 @@ public: QByteArray specularTextureFilename; QByteArray emissiveTextureFilename; QByteArray bumpTextureFilename; + QByteArray opacityTextureFilename; + OBJMaterialTextureOptions bumpTextureOptions; int illuminationModel; bool used { false }; From 402ed4fb76532327066d2ea1448556d68c906e6e Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Mon, 27 Aug 2018 10:35:17 -0700 Subject: [PATCH 116/545] More shared pointer tweaks --- assignment-client/src/avatars/AvatarMixerSlave.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index 3e9755ed39..367e991a04 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -288,7 +288,8 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // setup list of AvatarData as well as maps to map betweeen the AvatarData and the original nodes std::vector avatarsToSort; - std::unordered_map avatarDataToNodes; + std::unordered_map avatarDataToNodes; + std::unordered_map avatarDataToNodesShared; std::unordered_map avatarEncodeTimes; std::for_each(_begin, _end, [&](const SharedNodePointer& otherNode) { // make sure this is an agent that we have avatar data for before considering it for inclusion @@ -298,7 +299,8 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) AvatarData* otherAvatar = otherNodeData->getAvatarSharedPointer().get(); avatarsToSort.push_back(otherAvatar); - avatarDataToNodes[otherAvatar] = otherNode; + avatarDataToNodes[otherAvatar] = otherNode.data(); + avatarDataToNodesShared[otherAvatar] = otherNode; QUuid id = otherAvatar->getSessionUUID(); avatarEncodeTimes[id] = nodeData->getLastOtherAvatarEncodeTime(id); } @@ -332,9 +334,9 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) AvatarData::_avatarSortCoefficientAge); // ignore or sort - const AvatarSharedPointer& thisAvatar = nodeData->getAvatarSharedPointer(); + const AvatarData* thisAvatar = nodeData->getAvatarSharedPointer().get(); for (const auto avatar : avatarsToSort) { - if (avatar == thisAvatar.get()) { + if (avatar == thisAvatar) { // don't echo updates to self continue; } @@ -380,7 +382,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // Perform the collision check between the two bounding boxes if (nodeBox.touches(otherNodeBox)) { - nodeData->ignoreOther(node, avatarNode); + nodeData->ignoreOther(node, avatarDataToNodesShared[avatar]); shouldIgnore = !getsAnyIgnored; } } From e2cd695dfb9ada63d8a14664d4e75b13bf2ec978 Mon Sep 17 00:00:00 2001 From: danteruiz Date: Mon, 27 Aug 2018 11:01:29 -0700 Subject: [PATCH 117/545] PR code clean up --- interface/src/Application.h | 2 +- interface/src/avatar/MyAvatar.cpp | 1 - interface/src/octree/OctreePacketProcessor.cpp | 2 +- interface/src/octree/OctreePacketProcessor.h | 2 +- interface/src/scripting/WindowScriptingInterface.cpp | 2 +- interface/src/ui/OverlayConductor.cpp | 1 - libraries/entities-renderer/src/RenderableModelEntityItem.cpp | 1 - libraries/entities-renderer/src/RenderableModelEntityItem.h | 4 +--- 8 files changed, 5 insertions(+), 10 deletions(-) diff --git a/interface/src/Application.h b/interface/src/Application.h index a6258403a9..f3db4e718d 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -233,7 +233,7 @@ public: bool getPreferAvatarFingerOverStylus() { return false; } void setPreferAvatarFingerOverStylus(bool value); - float getDomainLoadProgress() { return _octreeProcessor.domainLoadProgress(); } + float getDomainLoadingProgress() { return _octreeProcessor.domainLoadingProgress(); } float getSettingConstrainToolbarPosition() { return _constrainToolbarPosition.get(); } void setSettingConstrainToolbarPosition(bool setting); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 545ca99109..923d071cc0 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -2432,7 +2432,6 @@ void MyAvatar::setHasScriptedBlendshapes(bool hasScriptedBlendshapes) { // send a forced avatarData update to make sure the script can send neutal blendshapes on unload // without having to wait for the update loop, make sure _hasScriptedBlendShapes is still true // before sending the update, or else it won't send the neutal blendshapes to the receiving clients - sendAvatarDataPacket(true); } _hasScriptedBlendShapes = hasScriptedBlendshapes; diff --git a/interface/src/octree/OctreePacketProcessor.cpp b/interface/src/octree/OctreePacketProcessor.cpp index e02c603415..e670153a77 100644 --- a/interface/src/octree/OctreePacketProcessor.cpp +++ b/interface/src/octree/OctreePacketProcessor.cpp @@ -142,6 +142,6 @@ bool OctreePacketProcessor::isEntitiesRenderReady() const { return _safeLanding->entitiesRenderReady(); } -float OctreePacketProcessor::domainLoadProgress() { +float OctreePacketProcessor::domainLoadingProgress() { return _safeLanding->loadingProgressPercentage(); } diff --git a/interface/src/octree/OctreePacketProcessor.h b/interface/src/octree/OctreePacketProcessor.h index 8e771de556..71e22bf240 100644 --- a/interface/src/octree/OctreePacketProcessor.h +++ b/interface/src/octree/OctreePacketProcessor.h @@ -28,7 +28,7 @@ public: void startEntitySequence(); bool isLoadSequenceComplete() const; bool isEntitiesRenderReady() const; - float domainLoadProgress(); + float domainLoadingProgress(); signals: void packetVersionMismatch(); diff --git a/interface/src/scripting/WindowScriptingInterface.cpp b/interface/src/scripting/WindowScriptingInterface.cpp index f422a6a8fa..b4c1563795 100644 --- a/interface/src/scripting/WindowScriptingInterface.cpp +++ b/interface/src/scripting/WindowScriptingInterface.cpp @@ -590,5 +590,5 @@ void WindowScriptingInterface::onMessageBoxSelected(int button) { float WindowScriptingInterface::domainLoadingProgress() { - return qApp->getDomainLoadProgress(); + return qApp->getDomainLoadingProgress(); } diff --git a/interface/src/ui/OverlayConductor.cpp b/interface/src/ui/OverlayConductor.cpp index 398f9cf147..e27001567f 100644 --- a/interface/src/ui/OverlayConductor.cpp +++ b/interface/src/ui/OverlayConductor.cpp @@ -103,7 +103,6 @@ void OverlayConductor::update(float dt) { bool targetVisible = Menu::getInstance()->isOptionChecked(MenuOption::Overlays) && !_suppressedByHead; if (targetVisible != currentVisible) { - qDebug() << "setting pinned: " << !targetVisible; offscreenUi->setPinned(!targetVisible); } if (shouldRecenter && !_suppressedByHead) { diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index baa20a0583..8be5b172ce 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -1305,7 +1305,6 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce if (_hasModel) { if (model && _didLastVisualGeometryRequestSucceed) { visuallyReady = (_prevModelLoaded && _texturesLoaded); - // qDebug() << visuallyReady; } } entity->setVisuallyReady(visuallyReady); diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 3540fa1127..45892fdd7f 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -38,13 +38,11 @@ class ModelEntityWrapper : public ModelEntityItem { using Parent = ModelEntityItem; friend class render::entities::ModelEntityRenderer; -public: - bool isModelLoaded() const; - protected: ModelEntityWrapper(const EntityItemID& entityItemID) : Parent(entityItemID) {} void setModel(const ModelPointer& model); ModelPointer getModel() const; + bool isModelLoaded() const; bool _needsInitialSimulation{ true }; private: From efa3fa7907a1490f095cc704141fd28139da9708 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Mon, 27 Aug 2018 20:42:06 +0200 Subject: [PATCH 118/545] Don't always on top InteractiveWindows (Windows OS) --- interface/resources/qml/InteractiveWindow.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/resources/qml/InteractiveWindow.qml b/interface/resources/qml/InteractiveWindow.qml index 800026710d..1c41dd189b 100644 --- a/interface/resources/qml/InteractiveWindow.qml +++ b/interface/resources/qml/InteractiveWindow.qml @@ -146,7 +146,8 @@ Windows.Window { Qt.WindowCloseButtonHint | Qt.WindowMaximizeButtonHint | Qt.WindowMinimizeButtonHint; - if ((flags & Desktop.ALWAYS_ON_TOP) === Desktop.ALWAYS_ON_TOP) { + // only use the always on top feature for non Windows OS + if (Qt.platform.os !== "windows" && (flags & Desktop.ALWAYS_ON_TOP) === Desktop.ALWAYS_ON_TOP) { nativeWindowFlags |= Qt.WindowStaysOnTopHint; } nativeWindow.flags = nativeWindowFlags; From 945982b1bdfa576ab07a2e8cbb416ed1f34c44f3 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 11 Jul 2018 14:05:07 -0700 Subject: [PATCH 119/545] Working on pauses in tomb domain --- libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp | 1 - libraries/gpu-gl-common/src/gpu/gl/GLTextureTransfer.cpp | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp index 01424c2ac6..c1848d99b1 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.cpp @@ -765,7 +765,6 @@ void GLBackend::recycle() const { } _textureManagement._transferEngine->manageMemory(); - Texture::KtxStorage::releaseOpenKtxFiles(); } void GLBackend::setCameraCorrection(const Mat4& correction, const Mat4& prevRenderView, bool reset) { diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLTextureTransfer.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLTextureTransfer.cpp index eaee054b7d..f4e81448cc 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLTextureTransfer.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLTextureTransfer.cpp @@ -405,6 +405,7 @@ bool GLTextureTransferEngineDefault::processActiveBufferQueue() { _activeTransferQueue.splice(_activeTransferQueue.end(), activeBufferQueue); } + Texture::KtxStorage::releaseOpenKtxFiles(); return true; } From 055f03878e1879f0b461e909e54d1cb1877379df Mon Sep 17 00:00:00 2001 From: amantley Date: Mon, 27 Aug 2018 14:44:27 -0700 Subject: [PATCH 120/545] made changes to add roll to the spine2 rotation. also only the shoulders control the rotation recenter now --- interface/src/avatar/MyAvatar.cpp | 70 +++++++++--------------- interface/src/avatar/MyAvatar.h | 4 +- interface/src/avatar/MySkeletonModel.cpp | 17 ++++-- libraries/shared/src/AvatarConstants.h | 2 +- 4 files changed, 41 insertions(+), 52 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 6012bc4419..c4d855ee77 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -447,6 +447,7 @@ void MyAvatar::reset(bool andRecenter, bool andReload, bool andHead) { void MyAvatar::update(float deltaTime) { // update moving average of HMD facing in xz plane. const float HMD_FACING_TIMESCALE = getRotationRecenterFilterLength(); + const float PERCENTAGE_WEIGHT_SHOULDERS_VS_HEAD_AZIMUTH = 0.0f; // 100 percent shoulders float tau = deltaTime / HMD_FACING_TIMESCALE; @@ -456,13 +457,13 @@ void MyAvatar::update(float deltaTime) { glm::mat4 sensorToWorldMat = getSensorToWorldMatrix(); glm::mat4 worldToSensorMat = glm::inverse(sensorToWorldMat); glm::vec3 handHipAzimuthSensorSpace = transformVectorFast(worldToSensorMat, glm::vec3(handHipAzimuthWorldSpace.x, 0.0f, handHipAzimuthWorldSpace.z)); - glm::vec2 normedHandHip = glm::normalize(glm::vec2(handHipAzimuthSensorSpace.x, handHipAzimuthSensorSpace.z)); - glm::vec2 headFacingPlusHandHipAzimuthMix = lerp(normedHandHip, _headControllerFacing, 0.5f); - // if head facing dot mid point hands facing is close to -1 and the hands midpoint is close to -1 you then flip - - // qCDebug(interfaceapp) << "the hand hip azimuth " << normedHandHip << "the head look at" << _headControllerFacing; - _headControllerFacingMovingAverage = lerp(_headControllerFacingMovingAverage, headFacingPlusHandHipAzimuthMix, tau); - // qCDebug(interfaceapp) << "the hand hip azimuth average " << _headControllerFacingMovingAverage; + glm::vec2 normedHandHipAzimuthSensorSpace = glm::normalize(glm::vec2(handHipAzimuthSensorSpace.x, handHipAzimuthSensorSpace.z)); + glm::vec2 headFacingPlusHandHipAzimuthMix = lerp(normedHandHipAzimuthSensorSpace, _headControllerFacing, PERCENTAGE_WEIGHT_SHOULDERS_VS_HEAD_AZIMUTH); + if (getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND).isValid() && getControllerPoseInAvatarFrame(controller::Action::RIGHT_HAND).isValid()) { + _headControllerFacingMovingAverage = lerp(_headControllerFacingMovingAverage, headFacingPlusHandHipAzimuthMix, tau); + } else { + _headControllerFacingMovingAverage = _headControllerFacing; + } if (_smoothOrientationTimer < SMOOTH_TIME_ORIENTATION) { _rotationChanged = usecTimestampNow(); @@ -477,7 +478,6 @@ void MyAvatar::update(float deltaTime) { computeHandAzimuth(); - #ifdef DEBUG_DRAW_HMD_MOVING_AVERAGE if (_drawAverageFacingEnabled) { auto sensorHeadPose = getControllerPoseInSensorFrame(controller::Action::HEAD); @@ -488,13 +488,7 @@ void MyAvatar::update(float deltaTime) { DebugDraw::getInstance().drawRay(worldHeadPos, worldHeadPos + worldFacingAverage, glm::vec4(0.0f, 0.0f, 1.0f, 1.0f)); // draw hand azimuth vector - glm::vec3 handAzimuthMidpoint = transformPoint(getTransform().getMatrix(), glm::vec3(_hipToHandController.x, 0.0f, _hipToHandController.y)); - glm::vec3 worldRHandAzimuth = transformPoint(getTransform().getMatrix(), getControllerPoseInAvatarFrame(controller::Action::RIGHT_HAND).getTranslation()); - glm::vec3 worldLHandAzimuth = transformPoint(getTransform().getMatrix(), getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND).getTranslation()); - //qCDebug(interfaceapp) << "the right hand in avatar space" << worldRHandAzimuth << " " << getWorldPosition(); - DebugDraw::getInstance().drawRay(getWorldPosition(), worldRHandAzimuth, glm::vec4(0.0f, 1.0f, 0.0f, 1.0f)); - DebugDraw::getInstance().drawRay(getWorldPosition(), worldLHandAzimuth, glm::vec4(0.0f, 1.0f, 0.0f, 1.0f)); DebugDraw::getInstance().drawRay(getWorldPosition(), handAzimuthMidpoint, glm::vec4(0.0f, 1.0f, 1.0f, 1.0f)); } #endif @@ -502,7 +496,11 @@ void MyAvatar::update(float deltaTime) { if (_goToPending) { setWorldPosition(_goToPosition); setWorldOrientation(_goToOrientation); - _headControllerFacingMovingAverage = _headControllerFacing; // reset moving average + if (getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND).isValid() && getControllerPoseInAvatarFrame(controller::Action::RIGHT_HAND).isValid()) { + _headControllerFacingMovingAverage = headFacingPlusHandHipAzimuthMix; + } else { + _headControllerFacingMovingAverage = _headControllerFacing; // reset moving average + } _goToPending = false; // updateFromHMDSensorMatrix (called from paintGL) expects that the sensorToWorldMatrix is updated for any position changes // that happen between render and Application::update (which calls updateSensorToWorldMatrix to do so). @@ -824,31 +822,29 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { } } +// Find the vector halfway between the hip to hand azimuth vectors +// This midpoint hand azimuth is in Avatar space void MyAvatar::computeHandAzimuth() { auto leftHandPoseAvatarSpace = getLeftHandPose(); auto rightHandPoseAvatarSpace = getRightHandPose(); glm::vec3 localLookat(0.0f, 0.0f, 1.0f); - // glm::vec3 rightHandRigSpace = rightHandPoseAvatarSpace.translation;// transformVectorFast(getTransform().getMatrix(), rightHandPoseAvatarSpace.translation); - // glm::vec3 leftHandRigSpace = leftHandPoseAvatarSpace.translation;// transformVectorFast(getTransform().getMatrix(), leftHandPoseAvatarSpace.translation); + const float HALFWAY = 0.50f; - // qCDebug(interfaceapp) << "the right hand in avatar space" << rightHandRigSpace; if (leftHandPoseAvatarSpace.isValid() && rightHandPoseAvatarSpace.isValid()) { + // we need the old azimuth reading to prevent flipping the facing direction 180 + // in the case where the hands go from being slightly less than 180 apart to slightly more than 180 apart. vec2 oldAzimuthReading = _hipToHandController; - _hipToHandController = lerp(glm::normalize(glm::vec2(rightHandPoseAvatarSpace.translation.x, rightHandPoseAvatarSpace.translation.z)), glm::normalize(glm::vec2(leftHandPoseAvatarSpace.translation.x, leftHandPoseAvatarSpace.translation.z)), 0.5f); - - //if they are 180 apart + _hipToHandController = lerp(glm::normalize(glm::vec2(rightHandPoseAvatarSpace.translation.x, rightHandPoseAvatarSpace.translation.z)), glm::normalize(glm::vec2(leftHandPoseAvatarSpace.translation.x, leftHandPoseAvatarSpace.translation.z)), HALFWAY); + + // check the angular distance from forward and back float cosForwardAngle = glm::dot(_hipToHandController, oldAzimuthReading); float cosBackwardAngle = glm::dot(_hipToHandController, -oldAzimuthReading); + // if we are now closer to the 180 flip of the previous chest forward + // then we negate our computed _hipToHandController to keep the chest in the same direction. if (cosBackwardAngle > cosForwardAngle) { // this means we have lost continuity with the current chest position _hipToHandController = -_hipToHandController; } - - - //need to use easing function here. - //var rotateAngle = ((Math.cos((leftRightMidpoint / 180.0) * Math.PI) + 2.0) / 3.0) * leftRightMidpoint; - } else { - // _hipToHandController = glm::vec2(0.0f, -1.0f); } } @@ -3382,11 +3378,9 @@ glm::mat4 MyAvatar::getSpine2RotationRigSpace() const { static const glm::quat RIG_CHANGE_OF_BASIS = Quaternions::Y_180; glm::vec3 hipToHandRigSpace = RIG_CHANGE_OF_BASIS * glm::vec3(_hipToHandController.x, 0.0f, _hipToHandController.y); - //to do: check for zero before normalizing. glm::vec3 u, v, w; generateBasisVectors(glm::vec3(0.0f,1.0f,0.0f), hipToHandRigSpace, u, v, w); glm::mat4 spine2RigSpace(glm::vec4(w, 0.0f), glm::vec4(u, 0.0f), glm::vec4(v, 0.0f), glm::vec4(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f)); - return spine2RigSpace; } @@ -3867,7 +3861,7 @@ void MyAvatar::lateUpdatePalms() { } -static const float FOLLOW_TIME = 0.1f; +static const float FOLLOW_TIME = 0.5f; MyAvatar::FollowHelper::FollowHelper() { deactivate(); @@ -3972,11 +3966,6 @@ bool MyAvatar::FollowHelper::shouldActivateHorizontalCG(MyAvatar& myAvatar) cons glm::vec3 defaultHeadPosition = myAvatar.getAbsoluteDefaultJointTranslationInObjectFrame(myAvatar.getJointIndex("Head")); glm::vec3 currentHeadPosition = currentHeadPose.getTranslation(); float anatomicalHeadToHipsDistance = glm::length(defaultHeadPosition - defaultHipsPosition); - //if (!isActive(Horizontal) && - // (glm::length(currentHeadPosition - defaultHipsPosition) > (anatomicalHeadToHipsDistance + DEFAULT_AVATAR_SPINE_STRETCH_LIMIT))) { - // myAvatar.setResetMode(true); - // stepDetected = true; - //} if (!isActive(Horizontal) && (glm::length(currentHeadPosition - defaultHipsPosition) > (anatomicalHeadToHipsDistance + (DEFAULT_AVATAR_SPINE_STRETCH_LIMIT * anatomicalHeadToHipsDistance * myAvatar.getAvatarScale())))) { myAvatar.setResetMode(true); @@ -3997,23 +3986,15 @@ bool MyAvatar::FollowHelper::shouldActivateVertical(const MyAvatar& myAvatar, co void MyAvatar::FollowHelper::prePhysicsUpdate(MyAvatar& myAvatar, const glm::mat4& desiredBodyMatrix, const glm::mat4& currentBodyMatrix, bool hasDriveInput) { - const float VELOCITY_THRESHHOLD = 1.0f; - float currentVelocity = glm::length(myAvatar.getLocalVelocity() / myAvatar.getSensorToWorldScale()); - if (myAvatar.getHMDLeanRecenterEnabled() && qApp->getCamera().getMode() != CAMERA_MODE_MIRROR) { - //if (!isActive(Rotation) && getForceActivateRotation()) { - // activate(Rotation); - // myAvatar.setHeadControllerFacingMovingAverage(myAvatar._headControllerFacing); - // setForceActivateRotation(false); - //} if (!isActive(Rotation) && (shouldActivateRotation(myAvatar, desiredBodyMatrix, currentBodyMatrix) || hasDriveInput)) { activate(Rotation); myAvatar.setHeadControllerFacingMovingAverage(myAvatar._headControllerFacing); } if (myAvatar.getCenterOfGravityModelEnabled()) { - if ((!isActive(Horizontal) && (shouldActivateHorizontalCG(myAvatar) || hasDriveInput)) || (isActive(Horizontal) && (currentVelocity > VELOCITY_THRESHHOLD))) { + if (!isActive(Horizontal) && (shouldActivateHorizontalCG(myAvatar) || hasDriveInput)) { activate(Horizontal); if (myAvatar.getEnableStepResetRotation()) { activate(Rotation); @@ -4029,7 +4010,6 @@ void MyAvatar::FollowHelper::prePhysicsUpdate(MyAvatar& myAvatar, const glm::mat } } } - if (!isActive(Vertical) && (shouldActivateVertical(myAvatar, desiredBodyMatrix, currentBodyMatrix) || hasDriveInput)) { activate(Vertical); } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index ea5059bf39..f819c417de 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -285,7 +285,7 @@ public: Q_INVOKABLE void centerBody(); // thread-safe - /**jsdoc + /**jsdoc_hmdSensorMatrix * The internal inverse-kinematics system maintains a record of which joints are "locked". Sometimes it is useful to forget this history, to prevent * contorted joints. * @function MyAvatar.clearIKJointLimitHistory @@ -914,6 +914,8 @@ public: virtual void rebuildCollisionShape() override; + const glm::vec2& getHeadControllerFacing() const { return _headControllerFacing; } + void setHeadControllerFacing(glm::vec2 currentHeadControllerFacing) { _headControllerFacing = currentHeadControllerFacing; } const glm::vec2& getHeadControllerFacingMovingAverage() const { return _headControllerFacingMovingAverage; } void setHeadControllerFacingMovingAverage(glm::vec2 currentHeadControllerFacing) { _headControllerFacingMovingAverage = currentHeadControllerFacing; } float getCurrentStandingHeight() const { return _currentStandingHeight; } diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 158f9bb0b6..f150379f0c 100644 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -238,13 +238,20 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { params.primaryControllerPoses[Rig::PrimaryControllerType_Hips] = sensorToRigPose * hips; params.primaryControllerFlags[Rig::PrimaryControllerType_Hips] = (uint8_t)Rig::ControllerFlags::Enabled | (uint8_t)Rig::ControllerFlags::Estimated; - - // spine 2 hack to be improved. + // set spine2 if we have hand controllers AnimPose currentPose; bool ret = _rig.getAbsoluteJointPoseInRigFrame(_rig.indexOfJoint("Spine2"),currentPose); - AnimPose newSpinePose(myAvatar->getSpine2RotationRigSpace()); - currentPose.rot() = newSpinePose.rot(); - //newSpinePose.rot() = myAvatar->getSpine2RotationRigSpace();// *newSpinePose.rot(); + AnimPose rigSpaceYaw(myAvatar->getSpine2RotationRigSpace()); + glm::vec3 u, v, w; + glm::vec3 fwd = rigSpaceYaw.rot() * glm::vec3(0.0f, 0.0f, 1.0f); + glm::vec3 up = currentPose.rot() * glm::vec3(0.0f, 1.0f, 0.0f); + generateBasisVectors(up, fwd, u, v, w); + AnimPose newSpinePose(glm::mat4(glm::vec4(w, 0.0f), glm::vec4(u, 0.0f), glm::vec4(v, 0.0f), glm::vec4(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f))); + + if (myAvatar->getControllerPoseInAvatarFrame(controller::Action::RIGHT_HAND).isValid() && myAvatar->getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND).isValid()) { + AnimPose newSpinePose(myAvatar->getSpine2RotationRigSpace()); + currentPose.rot() = newSpinePose.rot(); + } params.primaryControllerPoses[Rig::PrimaryControllerType_Spine2] = currentPose; params.primaryControllerFlags[Rig::PrimaryControllerType_Spine2] = (uint8_t)Rig::ControllerFlags::Enabled | (uint8_t)Rig::ControllerFlags::Estimated; diff --git a/libraries/shared/src/AvatarConstants.h b/libraries/shared/src/AvatarConstants.h index b97f586d32..c3e8a3f173 100644 --- a/libraries/shared/src/AvatarConstants.h +++ b/libraries/shared/src/AvatarConstants.h @@ -34,7 +34,7 @@ const float DEFAULT_HANDS_ANGULAR_VELOCITY_STEPPING_THRESHOLD = 3.3f; const float DEFAULT_HEAD_VELOCITY_STEPPING_THRESHOLD = 0.18f; const float DEFAULT_HEAD_PITCH_STEPPING_TOLERANCE = 7.0f; const float DEFAULT_HEAD_ROLL_STEPPING_TOLERANCE = 7.0f; -const float DEFAULT_AVATAR_SPINE_STRETCH_LIMIT = 0.05f; +const float DEFAULT_AVATAR_SPINE_STRETCH_LIMIT = 0.04f; const float DEFAULT_AVATAR_FORWARD_DAMPENING_FACTOR = 0.5f; const float DEFAULT_AVATAR_LATERAL_DAMPENING_FACTOR = 2.0f; const float DEFAULT_AVATAR_HIPS_MASS = 40.0f; From b6edb2c9d6afcc07d266b45fa63b3536e35469eb Mon Sep 17 00:00:00 2001 From: David Back Date: Mon, 27 Aug 2018 14:53:13 -0700 Subject: [PATCH 121/545] platform states, edit controller mapping, separate mac/win delete --- interface/src/Application.cpp | 27 ++++++++++++++++++- .../src/input-plugins/KeyboardMouseDevice.cpp | 2 ++ scripts/system/edit.js | 17 +++++++++--- 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e290531471..12aed213c9 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -726,6 +726,9 @@ static const QString STATE_SNAP_TURN = "SnapTurn"; static const QString STATE_ADVANCED_MOVEMENT_CONTROLS = "AdvancedMovement"; static const QString STATE_GROUNDED = "Grounded"; static const QString STATE_NAV_FOCUSED = "NavigationFocused"; +static const QString STATE_PLATFORM_WINDOWS = "PlatformWindows"; +static const QString STATE_PLATFORM_MAC = "PlatformMac"; +static const QString STATE_PLATFORM_ANDROID = "PlatformAndroid"; // Statically provided display and input plugins extern DisplayPluginList getDisplayPlugins(); @@ -909,7 +912,8 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { DependencyManager::set(); controller::StateController::setStateVariables({ { STATE_IN_HMD, STATE_CAMERA_FULL_SCREEN_MIRROR, STATE_CAMERA_FIRST_PERSON, STATE_CAMERA_THIRD_PERSON, STATE_CAMERA_ENTITY, STATE_CAMERA_INDEPENDENT, - STATE_SNAP_TURN, STATE_ADVANCED_MOVEMENT_CONTROLS, STATE_GROUNDED, STATE_NAV_FOCUSED } }); + STATE_SNAP_TURN, STATE_ADVANCED_MOVEMENT_CONTROLS, STATE_GROUNDED, STATE_NAV_FOCUSED, + STATE_PLATFORM_WINDOWS, STATE_PLATFORM_MAC, STATE_PLATFORM_WINDOWS } }); DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); @@ -1683,6 +1687,27 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo _applicationStateDevice->setInputVariant(STATE_NAV_FOCUSED, []() -> float { return DependencyManager::get()->navigationFocused() ? 1 : 0; }); + _applicationStateDevice->setInputVariant(STATE_PLATFORM_WINDOWS, []() -> float { +#if defined(Q_OS_WIN) + return 1; +#else + return 0; +#endif + }); + _applicationStateDevice->setInputVariant(STATE_PLATFORM_MAC, []() -> float { +#if defined(Q_OS_MAC) + return 1; +#else + return 0; +#endif + }); + _applicationStateDevice->setInputVariant(STATE_PLATFORM_ANDROID, []() -> float { +#if defined(Q_OS_ANDROID) + return 1; +#else + return 0; +#endif + }); // Setup the _keyboardMouseDevice, _touchscreenDevice, _touchscreenVirtualPadDevice and the user input mapper with the default bindings userInputMapper->registerDevice(_keyboardMouseDevice->getInputDevice()); diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp index 650c9675a7..ddd51e9b9b 100755 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp @@ -302,6 +302,8 @@ controller::Input::NamedVector KeyboardMouseDevice::InputDevice::getAvailableInp availableInputs.append(Input::NamedPair(makeInput(Qt::Key_PageDown), QKeySequence(Qt::Key_PageDown).toString())); availableInputs.append(Input::NamedPair(makeInput(Qt::Key_Tab), QKeySequence(Qt::Key_Tab).toString())); availableInputs.append(Input::NamedPair(makeInput(Qt::Key_Control), "Control")); + availableInputs.append(Input::NamedPair(makeInput(Qt::Key_Delete), "Delete")); + availableInputs.append(Input::NamedPair(makeInput(Qt::Key_Backspace), QKeySequence(Qt::Key_Backspace).toString())); availableInputs.append(Input::NamedPair(makeInput(Qt::LeftButton), "LeftMouseButton")); availableInputs.append(Input::NamedPair(makeInput(Qt::MiddleButton), "MiddleMouseButton")); diff --git a/scripts/system/edit.js b/scripts/system/edit.js index adee7c6236..776c09addd 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -20,6 +20,8 @@ var EDIT_TOGGLE_BUTTON = "com.highfidelity.interface.system.editButton"; +var CONTROLLER_MAPPING_NAME = "com.highfidelity.editMode"; + Script.include([ "libraries/stringHelpers.js", "libraries/dataViewHelpers.js", @@ -860,6 +862,7 @@ var toolBar = (function () { cameraManager.disable(); selectionDisplay.triggerMapping.disable(); tablet.landscape = false; + Controller.disableMapping(CONTROLLER_MAPPING_NAME); } else { if (shouldUseEditTabletApp()) { tablet.loadQMLSource("hifi/tablet/Edit.qml", true); @@ -876,6 +879,7 @@ var toolBar = (function () { selectionDisplay.triggerMapping.enable(); print("starting tablet in landscape mode"); tablet.landscape = true; + Controller.enableMapping(CONTROLLER_MAPPING_NAME); // Not sure what the following was meant to accomplish, but it currently causes // everybody else to think that Interface has lost focus overall. fogbugzid:558 // Window.setFocus(); @@ -1859,9 +1863,7 @@ var keyReleaseEvent = function (event) { cameraManager.keyReleaseEvent(event); } // since sometimes our menu shortcut keys don't work, trap our menu items here also and fire the appropriate menu items - if (event.text === "DELETE") { - deleteSelectedEntities(); - } else if (event.text === 'd' && event.isControl) { + if (event.text === 'd' && event.isControl) { selectionManager.clearSelections(); } else if (event.text === "t") { selectionDisplay.toggleSpaceMode(); @@ -1893,6 +1895,15 @@ var keyReleaseEvent = function (event) { Controller.keyReleaseEvent.connect(keyReleaseEvent); Controller.keyPressEvent.connect(keyPressEvent); +function deleteKey(value) { + if (value === 0) { // on release + deleteSelectedEntities(); + } +} +var mapping = Controller.newMapping(CONTROLLER_MAPPING_NAME); +mapping.from([Controller.Hardware.Keyboard.Delete]).when([Controller.Hardware.Application.PlatformWindows]).peek().to(deleteKey); +mapping.from([Controller.Hardware.Keyboard.Backspace]).when([Controller.Hardware.Application.PlatformMac]).peek().to(deleteKey); + function recursiveAdd(newParentID, parentData) { if (parentData.children !== undefined) { var children = parentData.children; From 44f253c482a9978c378e091d811e8358a785dc88 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Mon, 27 Aug 2018 14:54:37 -0700 Subject: [PATCH 122/545] Reduce use of shared pointers and maps --- .../src/avatars/AvatarMixerClientData.cpp | 4 +- .../src/avatars/AvatarMixerSlave.cpp | 60 ++++++++++--------- 2 files changed, 33 insertions(+), 31 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixerClientData.cpp b/assignment-client/src/avatars/AvatarMixerClientData.cpp index f524c071ec..e003fdd769 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.cpp +++ b/assignment-client/src/avatars/AvatarMixerClientData.cpp @@ -236,9 +236,7 @@ void AvatarMixerClientData::ignoreOther(SharedNodePointer self, SharedNodePointe } void AvatarMixerClientData::removeFromRadiusIgnoringSet(SharedNodePointer self, const QUuid& other) { - if (isRadiusIgnoring(other)) { - _radiusIgnoredOthers.erase(other); - } + _radiusIgnoredOthers.erase(other); } void AvatarMixerClientData::resetSentTraitData(Node::LocalID nodeLocalID) { diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index 367e991a04..2ba54bd6b6 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -287,30 +287,39 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // setup list of AvatarData as well as maps to map betweeen the AvatarData and the original nodes - std::vector avatarsToSort; - std::unordered_map avatarDataToNodes; - std::unordered_map avatarDataToNodesShared; - std::unordered_map avatarEncodeTimes; + struct AvatarSortData { + SharedNodePointer _nodeShared; + Node* _node; + AvatarData* _avatarData; + quint64 _lastEncodeTime; + }; + std::vector avatarsToSort; + avatarsToSort.reserve(nodeList->size()); + //std::unordered_map avatarDataToNodes; + //std::unordered_map avatarDataToNodesShared; + //std::unordered_map avatarEncodeTimes; std::for_each(_begin, _end, [&](const SharedNodePointer& otherNode) { + Node* otherNodeRaw = otherNode.data(); // make sure this is an agent that we have avatar data for before considering it for inclusion - if (otherNode->getType() == NodeType::Agent - && otherNode->getLinkedData()) { - const AvatarMixerClientData* otherNodeData = reinterpret_cast(otherNode->getLinkedData()); + if (otherNodeRaw->getType() == NodeType::Agent + && otherNodeRaw->getLinkedData()) { + const AvatarMixerClientData* otherNodeData = reinterpret_cast(otherNodeRaw->getLinkedData()); + AvatarData* otherAvatar = otherNodeData->getAvatarSharedPointer().get(); - avatarsToSort.push_back(otherAvatar); - avatarDataToNodes[otherAvatar] = otherNode.data(); - avatarDataToNodesShared[otherAvatar] = otherNode; - QUuid id = otherAvatar->getSessionUUID(); - avatarEncodeTimes[id] = nodeData->getLastOtherAvatarEncodeTime(id); + //avatarsToSort.push_back(otherAvatar); + //avatarDataToNodes[otherAvatar] = otherNode.data(); + //avatarDataToNodesShared[otherAvatar] = otherNode; + auto lastEncodeTime = nodeData->getLastOtherAvatarEncodeTime(otherAvatar->getSessionUUID()); + avatarsToSort.emplace_back(AvatarSortData({ otherNode, otherNodeRaw, otherAvatar, lastEncodeTime })); } }); class SortableAvatar: public PrioritySortUtil::Sortable { public: SortableAvatar() = delete; - SortableAvatar(const AvatarData* avatar, uint64_t lastEncodeTime) - : _avatar(avatar), _lastEncodeTime(lastEncodeTime) {} + SortableAvatar(const AvatarData* avatar, const Node* avatarNode, uint64_t lastEncodeTime) + : _avatar(avatar), _node(avatarNode), _lastEncodeTime(lastEncodeTime) {} glm::vec3 getPosition() const override { return _avatar->getWorldPosition(); } float getRadius() const override { glm::vec3 nodeBoxHalfScale = (_avatar->getWorldPosition() - _avatar->getGlobalBoundingBoxCorner() * _avatar->getSensorToWorldScale()); @@ -320,9 +329,11 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) return _lastEncodeTime; } const AvatarData* getAvatar() const { return _avatar; } + const Node* getNode() const { return _node; } private: const AvatarData* _avatar; + const Node* _node; uint64_t _lastEncodeTime; }; @@ -335,8 +346,8 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // ignore or sort const AvatarData* thisAvatar = nodeData->getAvatarSharedPointer().get(); - for (const auto avatar : avatarsToSort) { - if (avatar == thisAvatar) { + for (const auto& avatar : avatarsToSort) { + if (avatar._node == nodeRaw) { // don't echo updates to self continue; } @@ -348,7 +359,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // happen if for example the avatar is connected on a desktop and sending // updates at ~30hz. So every 3 frames we skip a frame. - auto avatarNode = avatarDataToNodes[avatar]; + auto avatarNode = avatar._node; assert(avatarNode); // we can't have gotten here without the avatarData being a valid key in the map const AvatarMixerClientData* avatarNodeData = reinterpret_cast(avatarNode->getLinkedData()); @@ -358,9 +369,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // make sure we have data for this avatar, that it isn't the same node, // and isn't an avatar that the viewing node has ignored // or that has ignored the viewing node - if (!avatarNode->getLinkedData() - || avatarNode->getUUID() == nodeRaw->getUUID() - || (nodeRaw->isIgnoringNodeWithID(avatarNode->getUUID()) && !PALIsOpen) + if ((nodeRaw->isIgnoringNodeWithID(avatarNode->getUUID()) && !PALIsOpen) || (avatarNode->isIgnoringNodeWithID(nodeRaw->getUUID()) && !getsAnyIgnored)) { shouldIgnore = true; } else { @@ -382,7 +391,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // Perform the collision check between the two bounding boxes if (nodeBox.touches(otherNodeBox)) { - nodeData->ignoreOther(node, avatarDataToNodesShared[avatar]); + nodeData->ignoreOther(node, avatar._nodeShared); shouldIgnore = !getsAnyIgnored; } } @@ -419,12 +428,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) if (!shouldIgnore) { // sort this one for later - uint64_t lastEncodeTime = 0; - std::unordered_map::const_iterator itr = avatarEncodeTimes.find(avatar->getSessionUUID()); - if (itr != avatarEncodeTimes.end()) { - lastEncodeTime = itr->second; - } - sortedAvatars.push(SortableAvatar(avatar, lastEncodeTime)); + sortedAvatars.push(SortableAvatar(avatar._avatarData, avatar._node, avatar._lastEncodeTime)); } } @@ -434,10 +438,10 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) auto traitsPacketList = NLPacketList::create(PacketType::BulkAvatarTraits, QByteArray(), true, true); while (!sortedAvatars.empty()) { const AvatarData* avatarData = sortedAvatars.top().getAvatar(); + const Node* otherNode = sortedAvatars.top().getNode(); sortedAvatars.pop(); remainingAvatars--; - auto otherNode = avatarDataToNodes[avatarData]; assert(otherNode); // we can't have gotten here without the avatarData being a valid key in the map // NOTE: Here's where we determine if we are over budget and drop to bare minimum data From a76b50ce3308c1d5c5805c4b45f86aace2c83080 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 27 Aug 2018 15:07:19 -0700 Subject: [PATCH 123/545] fix teardown of recording and ScriptEngine(s) --- assignment-client/src/Agent.cpp | 291 ++++++++++-------- .../src/avatars-renderer/Head.cpp | 1 - 2 files changed, 157 insertions(+), 135 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 2f03f15da7..47a64413c0 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -96,7 +96,6 @@ Agent::Agent(ReceivedMessage& message) : DependencyManager::set(); DependencyManager::set(); - DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); @@ -177,6 +176,8 @@ void Agent::run() { // Create ScriptEngines on threaded-assignment thread then move to main thread. DependencyManager::set(ScriptEngine::AGENT_SCRIPT)->moveToThread(qApp->thread()); + DependencyManager::set(); + // make sure we request our script once the agent connects to the domain auto nodeList = DependencyManager::get(); @@ -360,154 +361,168 @@ void Agent::scriptRequestFinished() { } void Agent::executeScript() { - _scriptEngine = scriptEngineFactory(ScriptEngine::AGENT_SCRIPT, _scriptContents, _payload); + // the following block is scoped so that any shared pointers we take here + // are cleared before we call setFinished at the end of the function + { + _scriptEngine = scriptEngineFactory(ScriptEngine::AGENT_SCRIPT, _scriptContents, _payload); - // setup an Avatar for the script to use - auto scriptedAvatar = DependencyManager::get(); + // setup an Avatar for the script to use + auto scriptedAvatar = DependencyManager::get(); - scriptedAvatar->setID(getSessionUUID()); + scriptedAvatar->setID(getSessionUUID()); - connect(_scriptEngine.data(), SIGNAL(update(float)), - scriptedAvatar.data(), SLOT(update(float)), Qt::ConnectionType::QueuedConnection); - scriptedAvatar->setForceFaceTrackerConnected(true); + connect(_scriptEngine.data(), SIGNAL(update(float)), + scriptedAvatar.data(), SLOT(update(float)), Qt::ConnectionType::QueuedConnection); + scriptedAvatar->setForceFaceTrackerConnected(true); - // call model URL setters with empty URLs so our avatar, if user, will have the default models - scriptedAvatar->setSkeletonModelURL(QUrl()); + // call model URL setters with empty URLs so our avatar, if user, will have the default models + scriptedAvatar->setSkeletonModelURL(QUrl()); - // force lazy initialization of the head data for the scripted avatar - // since it is referenced below by computeLoudness and getAudioLoudness - scriptedAvatar->getHeadOrientation(); + // force lazy initialization of the head data for the scripted avatar + // since it is referenced below by computeLoudness and getAudioLoudness + scriptedAvatar->getHeadOrientation(); - // give this AvatarData object to the script engine - _scriptEngine->registerGlobalObject("Avatar", scriptedAvatar.data()); + // give this AvatarData object to the script engine + _scriptEngine->registerGlobalObject("Avatar", scriptedAvatar.data()); - // give scripts access to the Users object - _scriptEngine->registerGlobalObject("Users", DependencyManager::get().data()); + // give scripts access to the Users object + _scriptEngine->registerGlobalObject("Users", DependencyManager::get().data()); - auto player = DependencyManager::get(); - connect(player.data(), &recording::Deck::playbackStateChanged, [=] { - if (player->isPlaying()) { - auto recordingInterface = DependencyManager::get(); - if (recordingInterface->getPlayFromCurrentLocation()) { - scriptedAvatar->setRecordingBasis(); + auto player = DependencyManager::get(); + connect(player.data(), &recording::Deck::playbackStateChanged, [&player, &scriptedAvatar] { + if (player->isPlaying()) { + auto recordingInterface = DependencyManager::get(); + if (recordingInterface->getPlayFromCurrentLocation()) { + scriptedAvatar->setRecordingBasis(); + } + } else { + scriptedAvatar->clearRecordingBasis(); } - } else { - scriptedAvatar->clearRecordingBasis(); - } - }); + }); - using namespace recording; - static const FrameType AVATAR_FRAME_TYPE = Frame::registerFrameType(AvatarData::FRAME_NAME); - Frame::registerFrameHandler(AVATAR_FRAME_TYPE, [scriptedAvatar](Frame::ConstPointer frame) { + using namespace recording; + static const FrameType AVATAR_FRAME_TYPE = Frame::registerFrameType(AvatarData::FRAME_NAME); + Frame::registerFrameHandler(AVATAR_FRAME_TYPE, [scriptedAvatar](Frame::ConstPointer frame) { + + auto recordingInterface = DependencyManager::get(); + bool useFrameSkeleton = recordingInterface->getPlayerUseSkeletonModel(); + + // FIXME - the ability to switch the avatar URL is not actually supported when playing back from a recording + if (!useFrameSkeleton) { + static std::once_flag warning; + std::call_once(warning, [] { + qWarning() << "Recording.setPlayerUseSkeletonModel(false) is not currently supported."; + }); + } + + AvatarData::fromFrame(frame->data, *scriptedAvatar); + }); + + using namespace recording; + static const FrameType AUDIO_FRAME_TYPE = Frame::registerFrameType(AudioConstants::getAudioFrameName()); + Frame::registerFrameHandler(AUDIO_FRAME_TYPE, [this, &scriptedAvatar](Frame::ConstPointer frame) { + static quint16 audioSequenceNumber{ 0 }; + + QByteArray audio(frame->data); + + if (_isNoiseGateEnabled) { + int16_t* samples = reinterpret_cast(audio.data()); + int numSamples = AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL; + _audioGate.render(samples, samples, numSamples); + } + + computeLoudness(&audio, scriptedAvatar); + + // state machine to detect gate opening and closing + bool audioGateOpen = (scriptedAvatar->getAudioLoudness() != 0.0f); + bool openedInLastBlock = !_audioGateOpen && audioGateOpen; // the gate just opened + bool closedInLastBlock = _audioGateOpen && !audioGateOpen; // the gate just closed + _audioGateOpen = audioGateOpen; + Q_UNUSED(openedInLastBlock); + + // the codec must be flushed to silence before sending silent packets, + // so delay the transition to silent packets by one packet after becoming silent. + auto packetType = PacketType::MicrophoneAudioNoEcho; + if (!audioGateOpen && !closedInLastBlock) { + packetType = PacketType::SilentAudioFrame; + } + + Transform audioTransform; + auto headOrientation = scriptedAvatar->getHeadOrientation(); + audioTransform.setTranslation(scriptedAvatar->getWorldPosition()); + audioTransform.setRotation(headOrientation); + + QByteArray encodedBuffer; + if (_encoder) { + _encoder->encode(audio, encodedBuffer); + } else { + encodedBuffer = audio; + } + + AbstractAudioInterface::emitAudioPacket(encodedBuffer.data(), encodedBuffer.size(), audioSequenceNumber, false, + audioTransform, scriptedAvatar->getWorldPosition(), glm::vec3(0), + packetType, _selectedCodecName); + }); + + auto avatarHashMap = DependencyManager::set(); + _scriptEngine->registerGlobalObject("AvatarList", avatarHashMap.data()); + + // register ourselves to the script engine + _scriptEngine->registerGlobalObject("Agent", new AgentScriptingInterface(this)); + + _scriptEngine->registerGlobalObject("AnimationCache", DependencyManager::get().data()); + _scriptEngine->registerGlobalObject("SoundCache", DependencyManager::get().data()); + + QScriptValue webSocketServerConstructorValue = _scriptEngine->newFunction(WebSocketServerClass::constructor); + _scriptEngine->globalObject().setProperty("WebSocketServer", webSocketServerConstructorValue); + + auto entityScriptingInterface = DependencyManager::get(); + + _scriptEngine->registerGlobalObject("EntityViewer", &_entityViewer); + + _scriptEngine->registerGetterSetter("location", LocationScriptingInterface::locationGetter, + LocationScriptingInterface::locationSetter); auto recordingInterface = DependencyManager::get(); - bool useFrameSkeleton = recordingInterface->getPlayerUseSkeletonModel(); + _scriptEngine->registerGlobalObject("Recording", recordingInterface.data()); - // FIXME - the ability to switch the avatar URL is not actually supported when playing back from a recording - if (!useFrameSkeleton) { - static std::once_flag warning; - std::call_once(warning, [] { - qWarning() << "Recording.setPlayerUseSkeletonModel(false) is not currently supported."; - }); + entityScriptingInterface->init(); + + _entityViewer.init(); + + entityScriptingInterface->setEntityTree(_entityViewer.getTree()); + + DependencyManager::set(_entityViewer.getTree()); + + _avatarAudioTimer.start(); + + // Agents should run at 45hz + static const int AVATAR_DATA_HZ = 45; + static const int AVATAR_DATA_IN_MSECS = MSECS_PER_SECOND / AVATAR_DATA_HZ; + QTimer* avatarDataTimer = new QTimer(this); + connect(avatarDataTimer, &QTimer::timeout, this, &Agent::processAgentAvatar); + avatarDataTimer->setSingleShot(false); + avatarDataTimer->setInterval(AVATAR_DATA_IN_MSECS); + avatarDataTimer->setTimerType(Qt::PreciseTimer); + avatarDataTimer->start(); + + _scriptEngine->run(); + + Frame::clearFrameHandler(AUDIO_FRAME_TYPE); + Frame::clearFrameHandler(AVATAR_FRAME_TYPE); + + if (recordingInterface->isPlaying()) { + recordingInterface->stopPlaying(); } - AvatarData::fromFrame(frame->data, *scriptedAvatar); - }); - - using namespace recording; - static const FrameType AUDIO_FRAME_TYPE = Frame::registerFrameType(AudioConstants::getAudioFrameName()); - Frame::registerFrameHandler(AUDIO_FRAME_TYPE, [this, &scriptedAvatar](Frame::ConstPointer frame) { - static quint16 audioSequenceNumber{ 0 }; - - QByteArray audio(frame->data); - - if (_isNoiseGateEnabled) { - int16_t* samples = reinterpret_cast(audio.data()); - int numSamples = AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL; - _audioGate.render(samples, samples, numSamples); + if (recordingInterface->isRecording()) { + recordingInterface->stopRecording(); } - computeLoudness(&audio, scriptedAvatar); + avatarDataTimer->stop(); + _avatarAudioTimer.stop(); + } - // state machine to detect gate opening and closing - bool audioGateOpen = (scriptedAvatar->getAudioLoudness() != 0.0f); - bool openedInLastBlock = !_audioGateOpen && audioGateOpen; // the gate just opened - bool closedInLastBlock = _audioGateOpen && !audioGateOpen; // the gate just closed - _audioGateOpen = audioGateOpen; - Q_UNUSED(openedInLastBlock); - - // the codec must be flushed to silence before sending silent packets, - // so delay the transition to silent packets by one packet after becoming silent. - auto packetType = PacketType::MicrophoneAudioNoEcho; - if (!audioGateOpen && !closedInLastBlock) { - packetType = PacketType::SilentAudioFrame; - } - - Transform audioTransform; - auto headOrientation = scriptedAvatar->getHeadOrientation(); - audioTransform.setTranslation(scriptedAvatar->getWorldPosition()); - audioTransform.setRotation(headOrientation); - - QByteArray encodedBuffer; - if (_encoder) { - _encoder->encode(audio, encodedBuffer); - } else { - encodedBuffer = audio; - } - - AbstractAudioInterface::emitAudioPacket(encodedBuffer.data(), encodedBuffer.size(), audioSequenceNumber, false, - audioTransform, scriptedAvatar->getWorldPosition(), glm::vec3(0), - packetType, _selectedCodecName); - }); - - auto avatarHashMap = DependencyManager::set(); - _scriptEngine->registerGlobalObject("AvatarList", avatarHashMap.data()); - - // register ourselves to the script engine - _scriptEngine->registerGlobalObject("Agent", new AgentScriptingInterface(this)); - - _scriptEngine->registerGlobalObject("AnimationCache", DependencyManager::get().data()); - _scriptEngine->registerGlobalObject("SoundCache", DependencyManager::get().data()); - - QScriptValue webSocketServerConstructorValue = _scriptEngine->newFunction(WebSocketServerClass::constructor); - _scriptEngine->globalObject().setProperty("WebSocketServer", webSocketServerConstructorValue); - - auto entityScriptingInterface = DependencyManager::get(); - - _scriptEngine->registerGlobalObject("EntityViewer", &_entityViewer); - - _scriptEngine->registerGetterSetter("location", LocationScriptingInterface::locationGetter, - LocationScriptingInterface::locationSetter); - - auto recordingInterface = DependencyManager::get(); - _scriptEngine->registerGlobalObject("Recording", recordingInterface.data()); - - entityScriptingInterface->init(); - - _entityViewer.init(); - - entityScriptingInterface->setEntityTree(_entityViewer.getTree()); - - DependencyManager::set(_entityViewer.getTree()); - - QMetaObject::invokeMethod(&_avatarAudioTimer, "start"); - - // Agents should run at 45hz - static const int AVATAR_DATA_HZ = 45; - static const int AVATAR_DATA_IN_MSECS = MSECS_PER_SECOND / AVATAR_DATA_HZ; - QTimer* avatarDataTimer = new QTimer(this); - connect(avatarDataTimer, &QTimer::timeout, this, &Agent::processAgentAvatar); - avatarDataTimer->setSingleShot(false); - avatarDataTimer->setInterval(AVATAR_DATA_IN_MSECS); - avatarDataTimer->setTimerType(Qt::PreciseTimer); - avatarDataTimer->start(); - - _scriptEngine->run(); - - Frame::clearFrameHandler(AUDIO_FRAME_TYPE); - Frame::clearFrameHandler(AVATAR_FRAME_TYPE); - - DependencyManager::destroy(); setFinished(true); } @@ -859,17 +874,25 @@ void Agent::aboutToFinish() { DependencyManager::destroy(); DependencyManager::destroy(); + DependencyManager::destroy(); DependencyManager::destroy(); DependencyManager::destroy(); DependencyManager::destroy(); - DependencyManager::destroy(); + + // drop our shared pointer to the script engine, then ask ScriptEngines to shutdown scripting + // this ensures that the ScriptEngine goes down before ScriptEngines + _scriptEngine.clear(); + + { + DependencyManager::get()->shutdownScripting(); + } + + DependencyManager::destroy(); DependencyManager::destroy(); DependencyManager::destroy(); - QMetaObject::invokeMethod(&_avatarAudioTimer, "stop"); - // cleanup codec & encoder if (_codec && _encoder) { _codec->releaseEncoder(_encoder); diff --git a/libraries/avatars-renderer/src/avatars-renderer/Head.cpp b/libraries/avatars-renderer/src/avatars-renderer/Head.cpp index bdee6d9147..9cf034863e 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Head.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Head.cpp @@ -14,7 +14,6 @@ #include #include -#include #include #include #include From aae06e8f49d2c0ecf33ccd8eb343992cb5d6379f Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 27 Aug 2018 15:40:33 -0700 Subject: [PATCH 124/545] faster aabox ray intersection and pre-computed inverse direction --- .../ui/overlays/ContextOverlayInterface.cpp | 2 +- interface/src/ui/overlays/Volume3DOverlay.cpp | 2 +- .../src/RenderablePolyVoxEntityItem.cpp | 4 +- libraries/entities/src/EntityTree.cpp | 5 +- libraries/entities/src/EntityTreeElement.cpp | 2 +- libraries/render-utils/src/Model.cpp | 9 +- libraries/render-utils/src/PickItemsJob.cpp | 3 +- libraries/shared/src/AABox.cpp | 6 +- libraries/shared/src/AABox.h | 2 +- libraries/shared/src/AACube.cpp | 6 +- libraries/shared/src/AACube.h | 6 +- libraries/shared/src/GeometryUtil.cpp | 89 +++++++------------ libraries/shared/src/GeometryUtil.h | 4 +- libraries/shared/src/TriangleSet.cpp | 16 ++-- libraries/shared/src/TriangleSet.h | 4 +- 15 files changed, 69 insertions(+), 91 deletions(-) diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index 789b1f9969..ba9a1f9fc9 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -180,7 +180,7 @@ bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID& float distance; BoxFace face; glm::vec3 normal; - boundingBox.findRayIntersection(cameraPosition, direction, distance, face, normal); + boundingBox.findRayIntersection(cameraPosition, direction, 1.0f / direction, distance, face, normal); float offsetAngle = -CONTEXT_OVERLAY_OFFSET_ANGLE; if (event.getID() == 1) { // "1" is left hand offsetAngle *= -1.0f; diff --git a/interface/src/ui/overlays/Volume3DOverlay.cpp b/interface/src/ui/overlays/Volume3DOverlay.cpp index c87650a77b..a307d445c0 100644 --- a/interface/src/ui/overlays/Volume3DOverlay.cpp +++ b/interface/src/ui/overlays/Volume3DOverlay.cpp @@ -88,7 +88,7 @@ bool Volume3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::ve // we can use the AABox's ray intersection by mapping our origin and direction into the overlays frame // and testing intersection there. - bool hit = _localBoundingBox.findRayIntersection(overlayFrameOrigin, overlayFrameDirection, distance, face, surfaceNormal); + bool hit = _localBoundingBox.findRayIntersection(overlayFrameOrigin, overlayFrameDirection, 1.0f / overlayFrameDirection, distance, face, surfaceNormal); if (hit) { surfaceNormal = transform.getRotation() * surfaceNormal; diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index af8d4fac86..2da5c30dc0 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -596,8 +596,8 @@ bool RenderablePolyVoxEntityItem::findDetailedRayIntersection(const glm::vec3& o voxelBox += result3 - Vectors::HALF; voxelBox += result3 + Vectors::HALF; - glm::vec4 directionInVoxel = wtvMatrix * glm::vec4(direction, 0.0f); - return voxelBox.findRayIntersection(glm::vec3(originInVoxel), glm::vec3(directionInVoxel), + glm::vec3 directionInVoxel = vec3(wtvMatrix * glm::vec4(direction, 0.0f)); + return voxelBox.findRayIntersection(glm::vec3(originInVoxel), directionInVoxel, 1.0f / directionInVoxel, distance, face, surfaceNormal); } diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 1cf6e45d5b..a7c88ddc7d 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -48,6 +48,7 @@ public: // Inputs glm::vec3 origin; glm::vec3 direction; + glm::vec3 invDirection; const QVector& entityIdsToInclude; const QVector& entityIdsToDiscard; bool visibleOnly; @@ -847,7 +848,7 @@ float findRayIntersectionSortingOp(const OctreeElementPointer& element, void* ex float boundDistance = FLT_MAX; BoxFace face; glm::vec3 surfaceNormal; - if (entityTreeElementPointer->getAACube().findRayIntersection(args->origin, args->direction, boundDistance, face, surfaceNormal)) { + if (entityTreeElementPointer->getAACube().findRayIntersection(args->origin, args->direction, args->invDirection, boundDistance, face, surfaceNormal)) { // Don't add this cell if it's already farther than our best distance so far if (boundDistance < args->distance) { distance = boundDistance; @@ -863,7 +864,7 @@ EntityItemID EntityTree::findRayIntersection(const glm::vec3& origin, const glm: OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, QVariantMap& extraInfo, Octree::lockType lockType, bool* accurateResult) { - RayArgs args = { origin, direction, entityIdsToInclude, entityIdsToDiscard, + RayArgs args = { origin, direction, 1.0f / direction, entityIdsToInclude, entityIdsToDiscard, visibleOnly, collidableOnly, precisionPicking, element, distance, face, surfaceNormal, extraInfo, EntityItemID() }; distance = FLT_MAX; diff --git a/libraries/entities/src/EntityTreeElement.cpp b/libraries/entities/src/EntityTreeElement.cpp index b7288755a6..efe5dafccf 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -215,7 +215,7 @@ EntityItemID EntityTreeElement::findDetailedRayIntersection(const glm::vec3& ori float localDistance; BoxFace localFace; glm::vec3 localSurfaceNormal; - if (entityFrameBox.findRayIntersection(entityFrameOrigin, entityFrameDirection, localDistance, + if (entityFrameBox.findRayIntersection(entityFrameOrigin, entityFrameDirection, 1.0f / entityFrameDirection, localDistance, localFace, localSurfaceNormal)) { if (entityFrameBox.contains(entityFrameOrigin) || localDistance < distance) { // now ask the entity if we actually intersect diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index ae3ee6e9a2..18ee05ddd4 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -376,7 +376,7 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g // we can use the AABox's intersection by mapping our origin and direction into the model frame // and testing intersection there. - if (modelFrameBox.findRayIntersection(modelFrameOrigin, modelFrameDirection, distance, face, surfaceNormal)) { + if (modelFrameBox.findRayIntersection(modelFrameOrigin, modelFrameDirection, 1.0f / modelFrameDirection, distance, face, surfaceNormal)) { QMutexLocker locker(&_mutex); float bestDistance = FLT_MAX; @@ -400,6 +400,7 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g glm::vec3 meshFrameOrigin = glm::vec3(worldToMeshMatrix * glm::vec4(origin, 1.0f)); glm::vec3 meshFrameDirection = glm::vec3(worldToMeshMatrix * glm::vec4(direction, 0.0f)); + glm::vec3 meshFrameInvDirection = 1.0f / meshFrameDirection; int shapeID = 0; int subMeshIndex = 0; @@ -415,8 +416,8 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g float partBoundDistance = FLT_MAX; BoxFace partBoundFace; glm::vec3 partBoundNormal; - if (partTriangleSet.getBounds().findRayIntersection(meshFrameOrigin, meshFrameDirection, partBoundDistance, - partBoundFace, partBoundNormal)) { + if (partTriangleSet.getBounds().findRayIntersection(meshFrameOrigin, meshFrameDirection, meshFrameInvDirection, + partBoundDistance, partBoundFace, partBoundNormal)) { priority = partBoundDistance; } } @@ -444,7 +445,7 @@ bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const g float triangleSetDistance = FLT_MAX; BoxFace triangleSetFace; Triangle triangleSetTriangle; - if (sortedTriangleSet.triangleSet->findRayIntersection(meshFrameOrigin, meshFrameDirection, triangleSetDistance, triangleSetFace, + if (sortedTriangleSet.triangleSet->findRayIntersection(meshFrameOrigin, meshFrameDirection, meshFrameInvDirection, triangleSetDistance, triangleSetFace, triangleSetTriangle, pickAgainstTriangles, allowBackface)) { if (triangleSetDistance < bestDistance) { bestDistance = triangleSetDistance; diff --git a/libraries/render-utils/src/PickItemsJob.cpp b/libraries/render-utils/src/PickItemsJob.cpp index 860262a969..f41222d358 100644 --- a/libraries/render-utils/src/PickItemsJob.cpp +++ b/libraries/render-utils/src/PickItemsJob.cpp @@ -33,6 +33,7 @@ void PickItemsJob::run(const render::RenderContextPointer& renderContext, const render::ItemBound PickItemsJob::findNearestItem(const render::RenderContextPointer& renderContext, const render::ItemBounds& inputs, float& minIsectDistance) const { const glm::vec3 rayOrigin = renderContext->args->getViewFrustum().getPosition(); const glm::vec3 rayDirection = renderContext->args->getViewFrustum().getDirection(); + const glm::vec3 rayInvDirection = 1.0f / rayDirection; BoxFace face; glm::vec3 normal; float isectDistance; @@ -42,7 +43,7 @@ render::ItemBound PickItemsJob::findNearestItem(const render::RenderContextPoint render::ItemKey itemKey; for (const auto& itemBound : inputs) { - if (!itemBound.bound.contains(rayOrigin) && itemBound.bound.findRayIntersection(rayOrigin, rayDirection, isectDistance, face, normal)) { + if (!itemBound.bound.contains(rayOrigin) && itemBound.bound.findRayIntersection(rayOrigin, rayDirection, rayInvDirection, isectDistance, face, normal)) { auto& item = renderContext->_scene->getItem(itemBound.id); itemKey = item.getKey(); if (itemKey.isWorldSpace() && isectDistance>minDistance && isectDistance < minIsectDistance && isectDistance= 0 && - isWithin(origin.y + axisDistance * direction.y, corner.y, scale.y) && - isWithin(origin.z + axisDistance * direction.z, corner.z, scale.z))) { - distance = axisDistance; - face = direction.x > 0 ? MAX_X_FACE : MIN_X_FACE; - surfaceNormal = glm::vec3(direction.x > 0 ? 1.0f : -1.0f, 0.0f, 0.0f); - return true; - } - if ((findInsideOutIntersection(origin.y, direction.y, corner.y, scale.y, axisDistance) && axisDistance >= 0 && - isWithin(origin.x + axisDistance * direction.x, corner.x, scale.x) && - isWithin(origin.z + axisDistance * direction.z, corner.z, scale.z))) { - distance = axisDistance; - face = direction.y > 0 ? MAX_Y_FACE : MIN_Y_FACE; - surfaceNormal = glm::vec3(0.0f, direction.y > 0 ? 1.0f : -1.0f, 0.0f); - return true; - } - if ((findInsideOutIntersection(origin.z, direction.z, corner.z, scale.z, axisDistance) && axisDistance >= 0 && - isWithin(origin.y + axisDistance * direction.y, corner.y, scale.y) && - isWithin(origin.x + axisDistance * direction.x, corner.x, scale.x))) { - distance = axisDistance; - face = direction.z > 0 ? MAX_Z_FACE : MIN_Z_FACE; - surfaceNormal = glm::vec3(0.0f, 0.0f, direction.z > 0 ? 1.0f : -1.0f); - return true; - } - // This case is unexpected, but mimics the previous behavior for inside out intersections - distance = 0; - return true; +// https://tavianator.com/fast-branchless-raybounding-box-intersections/ +bool findRayAABoxIntersection(const glm::vec3& origin, const glm::vec3& direction, const glm::vec3& invDirection, + const glm::vec3& corner, const glm::vec3& scale, float& distance, BoxFace& face, glm::vec3& surfaceNormal) { + float t1, t2, newTmin, newTmax, tmin = -INFINITY, tmax = INFINITY; + int minAxis = -1, maxAxis = -1; + + for (int i = 0; i < 3; ++i) { + t1 = (corner[i] - origin[i]) * invDirection[i]; + t2 = (corner[i] + scale[i] - origin[i]) * invDirection[i]; + + newTmin = glm::min(t1, t2); + newTmax = glm::max(t1, t2); + + minAxis = newTmin > tmin ? i : minAxis; + tmin = glm::max(tmin, newTmin); + maxAxis = newTmax < tmax ? i : maxAxis; + tmax = glm::min(tmax, newTmax); } - // check each axis - float axisDistance; - if ((findIntersection(origin.x, direction.x, corner.x, scale.x, axisDistance) && axisDistance >= 0 && - isWithin(origin.y + axisDistance * direction.y, corner.y, scale.y) && - isWithin(origin.z + axisDistance * direction.z, corner.z, scale.z))) { - distance = axisDistance; - face = direction.x > 0 ? MIN_X_FACE : MAX_X_FACE; - surfaceNormal = glm::vec3(direction.x > 0 ? -1.0f : 1.0f, 0.0f, 0.0f); - return true; - } - if ((findIntersection(origin.y, direction.y, corner.y, scale.y, axisDistance) && axisDistance >= 0 && - isWithin(origin.x + axisDistance * direction.x, corner.x, scale.x) && - isWithin(origin.z + axisDistance * direction.z, corner.z, scale.z))) { - distance = axisDistance; - face = direction.y > 0 ? MIN_Y_FACE : MAX_Y_FACE; - surfaceNormal = glm::vec3(0.0f, direction.y > 0 ? -1.0f : 1.0f, 0.0f); - return true; - } - if ((findIntersection(origin.z, direction.z, corner.z, scale.z, axisDistance) && axisDistance >= 0 && - isWithin(origin.y + axisDistance * direction.y, corner.y, scale.y) && - isWithin(origin.x + axisDistance * direction.x, corner.x, scale.x))) { - distance = axisDistance; - face = direction.z > 0 ? MIN_Z_FACE : MAX_Z_FACE; - surfaceNormal = glm::vec3(0.0f, 0.0f, direction.z > 0 ? -1.0f : 1.0f); + bool inside = tmin < 0.0f; + if (tmax >= glm::max(tmin, 0.0f)) { + if (inside) { + distance = tmax; + bool positiveDirection = direction[maxAxis] > 0.0f; + surfaceNormal = glm::vec3(0.0f); + surfaceNormal[maxAxis] = positiveDirection ? -1.0f : 1.0f; + face = positiveDirection ? BoxFace(2 * maxAxis + 1) : BoxFace(2 * maxAxis); + } else { + distance = tmin; + bool positiveDirection = direction[minAxis] > 0.0f; + surfaceNormal = glm::vec3(0.0f); + surfaceNormal[minAxis] = positiveDirection ? -1.0f : 1.0f; + face = positiveDirection ? BoxFace(2 * minAxis) : BoxFace(2 * minAxis + 1); + } return true; } return false; diff --git a/libraries/shared/src/GeometryUtil.h b/libraries/shared/src/GeometryUtil.h index 54f9062469..8ec75f71bd 100644 --- a/libraries/shared/src/GeometryUtil.h +++ b/libraries/shared/src/GeometryUtil.h @@ -76,8 +76,8 @@ glm::vec3 addPenetrations(const glm::vec3& currentPenetration, const glm::vec3& bool findIntersection(float origin, float direction, float corner, float size, float& distance); bool findInsideOutIntersection(float origin, float direction, float corner, float size, float& distance); -bool findRayAABoxIntersection(const glm::vec3& origin, const glm::vec3& direction, const glm::vec3& corner, const glm::vec3& scale, float& distance, - BoxFace& face, glm::vec3& surfaceNormal); +bool findRayAABoxIntersection(const glm::vec3& origin, const glm::vec3& direction, const glm::vec3& invDirection, + const glm::vec3& corner, const glm::vec3& scale, float& distance, BoxFace& face, glm::vec3& surfaceNormal); bool findRaySphereIntersection(const glm::vec3& origin, const glm::vec3& direction, const glm::vec3& center, float radius, float& distance); diff --git a/libraries/shared/src/TriangleSet.cpp b/libraries/shared/src/TriangleSet.cpp index 1dc8c5657a..02a8d458a9 100644 --- a/libraries/shared/src/TriangleSet.cpp +++ b/libraries/shared/src/TriangleSet.cpp @@ -176,7 +176,7 @@ void TriangleSet::TriangleTreeCell::insert(size_t triangleIndex) { _triangleIndices.push_back(triangleIndex); } -bool TriangleSet::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, +bool TriangleSet::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, const glm::vec3& invDirection, float& distance, BoxFace& face, Triangle& triangle, bool precision, bool allowBackface) { if (!_isBalanced) { balanceTree(); @@ -184,7 +184,7 @@ bool TriangleSet::findRayIntersection(const glm::vec3& origin, const glm::vec3& float localDistance = distance; int trianglesTouched = 0; - bool hit = _triangleTree.findRayIntersection(origin, direction, localDistance, face, triangle, precision, trianglesTouched, allowBackface); + bool hit = _triangleTree.findRayIntersection(origin, direction, invDirection, localDistance, face, triangle, precision, trianglesTouched, allowBackface); if (hit) { distance = localDistance; } @@ -232,9 +232,9 @@ bool TriangleSet::TriangleTreeCell::findRayIntersectionInternal(const glm::vec3& return intersectedSomething; } -bool TriangleSet::TriangleTreeCell::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, - BoxFace& face, Triangle& triangle, bool precision, int& trianglesTouched, - bool allowBackface) { +bool TriangleSet::TriangleTreeCell::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, const glm::vec3& invDirection, + float& distance, BoxFace& face, Triangle& triangle, bool precision, int& trianglesTouched, + bool allowBackface) { if (_population < 1) { return false; // no triangles below here, so we can't intersect } @@ -270,7 +270,7 @@ bool TriangleSet::TriangleTreeCell::findRayIntersection(const glm::vec3& origin, float childBoundDistance = FLT_MAX; BoxFace childBoundFace; glm::vec3 childBoundNormal; - if (child->getBounds().findRayIntersection(origin, direction, childBoundDistance, childBoundFace, childBoundNormal)) { + if (child->getBounds().findRayIntersection(origin, direction, invDirection, childBoundDistance, childBoundFace, childBoundNormal)) { // We only need to add this cell if it's closer than the local triangle set intersection (if there was one) if (childBoundDistance < bestLocalDistance) { priority = childBoundDistance; @@ -301,11 +301,11 @@ bool TriangleSet::TriangleTreeCell::findRayIntersection(const glm::vec3& origin, if (!precision && childDistance < EPSILON) { BoxFace childBoundFace; glm::vec3 childBoundNormal; - sortedTriangleCell.second->getBounds().findRayIntersection(origin, direction, childDistance, childBoundFace, childBoundNormal); + sortedTriangleCell.second->getBounds().findRayIntersection(origin, direction, invDirection, childDistance, childBoundFace, childBoundNormal); } BoxFace childFace; Triangle childTriangle; - if (sortedTriangleCell.second->findRayIntersection(origin, direction, childDistance, childFace, childTriangle, precision, trianglesTouched)) { + if (sortedTriangleCell.second->findRayIntersection(origin, direction, invDirection, childDistance, childFace, childTriangle, precision, trianglesTouched)) { if (childDistance < bestLocalDistance) { bestLocalDistance = childDistance; bestLocalFace = childFace; diff --git a/libraries/shared/src/TriangleSet.h b/libraries/shared/src/TriangleSet.h index 84e362f0d0..3417b36b4a 100644 --- a/libraries/shared/src/TriangleSet.h +++ b/libraries/shared/src/TriangleSet.h @@ -28,7 +28,7 @@ class TriangleSet { void reset(const AABox& bounds, int depth = 0); void clear(); - bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, + bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, const glm::vec3& invDirection, float& distance, BoxFace& face, Triangle& triangle, bool precision, int& trianglesTouched, bool allowBackface = false); bool findParabolaIntersection(const glm::vec3& origin, const glm::vec3& velocity, const glm::vec3& acceleration, @@ -69,7 +69,7 @@ public: void insert(const Triangle& t); - bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, + bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, const glm::vec3& invDirection, float& distance, BoxFace& face, Triangle& triangle, bool precision, bool allowBackface = false); bool findParabolaIntersection(const glm::vec3& origin, const glm::vec3& velocity, const glm::vec3& acceleration, float& parabolicDistance, BoxFace& face, Triangle& triangle, bool precision, bool allowBackface = false); From c29c9f98c1d46a3665aa5dd3ba3b097333cc9d6b Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 28 Aug 2018 11:15:57 +1200 Subject: [PATCH 125/545] Make Cancel in HMD settings dialogs return to Settings dialog --- .../hifi/tablet/tabletWindows/TabletPreferencesDialog.qml | 6 +++++- interface/src/Menu.cpp | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/hifi/tablet/tabletWindows/TabletPreferencesDialog.qml b/interface/resources/qml/hifi/tablet/tabletWindows/TabletPreferencesDialog.qml index 05f45dc61e..31d246be2d 100644 --- a/interface/resources/qml/hifi/tablet/tabletWindows/TabletPreferencesDialog.qml +++ b/interface/resources/qml/hifi/tablet/tabletWindows/TabletPreferencesDialog.qml @@ -50,7 +50,11 @@ Item { section.restoreAll(); } - closeDialog(); + if (HMD.active) { + tablet.popFromStack(); + } else { + closeDialog(); + } } function closeDialog() { diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index a7d7dcf8b3..72191de994 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -254,7 +254,7 @@ Menu::Menu() { connect(action, &QAction::triggered, [] { auto tablet = DependencyManager::get()->getTablet("com.highfidelity.interface.tablet.system"); auto hmd = DependencyManager::get(); - tablet->loadQMLSource("hifi/tablet/ControllerSettings.qml"); + tablet->pushOntoStack("hifi/tablet/ControllerSettings.qml"); if (!hmd->getShouldShowTablet()) { hmd->toggleShouldShowTablet(); From 52bbb4d2abac51afe38fe5050a168464625d1ce3 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 27 Aug 2018 12:47:17 -0700 Subject: [PATCH 126/545] fix ray-pick results on entities with non-default registration point. clean up grab scripts to correctly use this fix. --- interface/src/raypick/PathPointer.cpp | 4 +-- .../controllerModules/farActionGrabEntity.js | 18 +++-------- .../farActionGrabEntityDynOnly.js | 17 +++------- .../controllerModules/farParentGrabEntity.js | 18 +++-------- .../libraries/controllerDispatcherUtils.js | 32 +++++++++++++++++-- 5 files changed, 45 insertions(+), 44 deletions(-) diff --git a/interface/src/raypick/PathPointer.cpp b/interface/src/raypick/PathPointer.cpp index 685611d77b..d434c667de 100644 --- a/interface/src/raypick/PathPointer.cpp +++ b/interface/src/raypick/PathPointer.cpp @@ -105,7 +105,7 @@ PickResultPointer PathPointer::getVisualPickResult(const PickResultPointer& pick glm::mat4 entityMat = createMatFromQuatAndPos(props.getRotation(), props.getPosition()); glm::mat4 finalPosAndRotMat = entityMat * _lockEndObject.offsetMat; pos = extractTranslation(finalPosAndRotMat); - rot = glmExtractRotation(finalPosAndRotMat); + rot = props.getRotation(); dim = props.getDimensions(); registrationPoint = props.getRegistrationPoint(); } @@ -350,4 +350,4 @@ glm::vec2 PathPointer::findPos2D(const PickedObject& pickedObject, const glm::ve default: return glm::vec2(NAN); } -} \ No newline at end of file +} diff --git a/scripts/system/controllers/controllerModules/farActionGrabEntity.js b/scripts/system/controllers/controllerModules/farActionGrabEntity.js index e4563fda14..5e798ed680 100644 --- a/scripts/system/controllers/controllerModules/farActionGrabEntity.js +++ b/scripts/system/controllers/controllerModules/farActionGrabEntity.js @@ -14,7 +14,8 @@ PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC, ensureDynamic, getControllerWorldLocation, projectOntoEntityXYPlane, ContextOverlay, HMD, Reticle, Overlays, isPointingAtUI - Picks, makeLaserLockInfo Xform, makeLaserParams, AddressManager, getEntityParents, Selection, DISPATCHER_HOVERING_LIST + Picks, makeLaserLockInfo Xform, makeLaserParams, AddressManager, getEntityParents, Selection, DISPATCHER_HOVERING_LIST, + worldPositionToRegistrationFrameMatrix */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); @@ -593,18 +594,9 @@ Script.include("/~/system/libraries/Xform.js"); this.calculateOffset = function(controllerData) { if (this.distanceHolding || this.distanceRotating) { - var targetProps = Entities.getEntityProperties(this.targetObject.entityID, [ - "position", - "rotation" - ]); - var zeroVector = { x: 0, y: 0, z:0, w: 0 }; - var intersection = controllerData.rayPicks[this.hand].intersection; - var intersectionMat = new Xform(zeroVector, intersection); - var modelMat = new Xform(targetProps.rotation, targetProps.position); - var modelMatInv = modelMat.inv(); - var xformMat = Xform.mul(modelMatInv, intersectionMat); - var offsetMat = Mat4.createFromRotAndTrans(xformMat.rot, xformMat.pos); - return offsetMat; + var targetProps = Entities.getEntityProperties(this.targetObject.entityID, + [ "position", "rotation", "registrationPoint", "dimensions" ]); + return worldPositionToRegistrationFrameMatrix(targetProps, controllerData.rayPicks[this.hand].intersection); } return undefined; }; diff --git a/scripts/system/controllers/controllerModules/farActionGrabEntityDynOnly.js b/scripts/system/controllers/controllerModules/farActionGrabEntityDynOnly.js index a080e75325..78abcb9b20 100644 --- a/scripts/system/controllers/controllerModules/farActionGrabEntityDynOnly.js +++ b/scripts/system/controllers/controllerModules/farActionGrabEntityDynOnly.js @@ -12,7 +12,7 @@ makeDispatcherModuleParameters, MSECS_PER_SEC, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC, getControllerWorldLocation, projectOntoEntityXYPlane, ContextOverlay, HMD, Picks, makeLaserLockInfo, Xform, makeLaserParams, AddressManager, getEntityParents, Selection, DISPATCHER_HOVERING_LIST, - Uuid + Uuid, worldPositionToRegistrationFrameMatrix */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); @@ -572,18 +572,9 @@ Script.include("/~/system/libraries/Xform.js"); this.calculateOffset = function(controllerData) { if (this.distanceHolding || this.distanceRotating) { - var targetProps = Entities.getEntityProperties(this.targetObject.entityID, [ - "position", - "rotation" - ]); - var zeroVector = { x: 0, y: 0, z:0, w: 0 }; - var intersection = controllerData.rayPicks[this.hand].intersection; - var intersectionMat = new Xform(zeroVector, intersection); - var modelMat = new Xform(targetProps.rotation, targetProps.position); - var modelMatInv = modelMat.inv(); - var xformMat = Xform.mul(modelMatInv, intersectionMat); - var offsetMat = Mat4.createFromRotAndTrans(xformMat.rot, xformMat.pos); - return offsetMat; + var targetProps = Entities.getEntityProperties(this.targetObject.entityID, + [ "position", "rotation", "registrationPoint", "dimensions" ]); + return worldPositionToRegistrationFrameMatrix(targetProps, controllerData.rayPicks[this.hand].intersection); } return undefined; }; diff --git a/scripts/system/controllers/controllerModules/farParentGrabEntity.js b/scripts/system/controllers/controllerModules/farParentGrabEntity.js index 439b5e5f51..a9ec246a32 100644 --- a/scripts/system/controllers/controllerModules/farParentGrabEntity.js +++ b/scripts/system/controllers/controllerModules/farParentGrabEntity.js @@ -11,7 +11,8 @@ Entities, enableDispatcherModule, disableDispatcherModule, entityIsGrabbable, makeDispatcherModuleParameters, MSECS_PER_SEC, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC, getControllerWorldLocation, projectOntoEntityXYPlane, ContextOverlay, HMD, Picks, makeLaserLockInfo, Xform, makeLaserParams, AddressManager, - getEntityParents, Selection, DISPATCHER_HOVERING_LIST, unhighlightTargetEntity, Messages, Uuid, findGroupParent + getEntityParents, Selection, DISPATCHER_HOVERING_LIST, unhighlightTargetEntity, Messages, Uuid, findGroupParent, + worldPositionToRegistrationFrameMatrix */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); @@ -615,18 +616,9 @@ Script.include("/~/system/libraries/Xform.js"); this.calculateOffset = function(controllerData) { if (this.distanceHolding || this.distanceRotating) { - var targetProps = Entities.getEntityProperties(this.targetObject.entityID, [ - "position", - "rotation" - ]); - var zeroVector = { x: 0, y: 0, z:0, w: 0 }; - var intersection = controllerData.rayPicks[this.hand].intersection; - var intersectionMat = new Xform(zeroVector, intersection); - var modelMat = new Xform(targetProps.rotation, targetProps.position); - var modelMatInv = modelMat.inv(); - var xformMat = Xform.mul(modelMatInv, intersectionMat); - var offsetMat = Mat4.createFromRotAndTrans(xformMat.rot, xformMat.pos); - return offsetMat; + var targetProps = Entities.getEntityProperties(this.targetObject.entityID, + [ "position", "rotation", "registrationPoint", "dimensions" ]); + return worldPositionToRegistrationFrameMatrix(targetProps, controllerData.rayPicks[this.hand].intersection); } return undefined; }; diff --git a/scripts/system/libraries/controllerDispatcherUtils.js b/scripts/system/libraries/controllerDispatcherUtils.js index a386dcf5b4..c34fd76802 100644 --- a/scripts/system/libraries/controllerDispatcherUtils.js +++ b/scripts/system/libraries/controllerDispatcherUtils.js @@ -5,7 +5,7 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -/* global module, Camera, HMD, MyAvatar, controllerDispatcherPlugins:true, Quat, Vec3, Overlays, Xform, +/* global module, Camera, HMD, MyAvatar, controllerDispatcherPlugins:true, Quat, Vec3, Overlays, Xform, Mat4, Selection, Uuid, MSECS_PER_SEC:true , LEFT_HAND:true, RIGHT_HAND:true, FORBIDDEN_GRAB_TYPES:true, HAPTIC_PULSE_STRENGTH:true, HAPTIC_PULSE_DURATION:true, ZERO_VEC:true, ONE_VEC:true, @@ -58,7 +58,8 @@ highlightTargetEntity:true, clearHighlightedEntities:true, unhighlightTargetEntity:true, - distanceBetweenEntityLocalPositionAndBoundingBox: true + distanceBetweenEntityLocalPositionAndBoundingBox: true, + worldPositionToRegistrationFrameMatrix: true */ MSECS_PER_SEC = 1000.0; @@ -487,6 +488,30 @@ entityIsFarGrabbedByOther = function(entityID) { return false; }; + +worldPositionToRegistrationFrameMatrix = function(wptrProps, pos) { + // get world matrix for intersection point + var intersectionMat = new Xform({ x: 0, y: 0, z:0, w: 1 }, pos); + + // calculate world matrix for registrationPoint addjusted entity + var DEFAULT_REGISTRATION_POINT = { x: 0.5, y: 0.5, z: 0.5 }; + var regRatio = Vec3.subtract(DEFAULT_REGISTRATION_POINT, wptrProps.registrationPoint); + var regOffset = Vec3.multiplyVbyV(regRatio, wptrProps.dimensions); + var regOffsetRot = Vec3.multiplyQbyV(wptrProps.rotation, regOffset); + var modelMat = new Xform(wptrProps.rotation, Vec3.sum(wptrProps.position, regOffsetRot)); + + // get inverse of model matrix + var modelMatInv = modelMat.inv(); + + // transform world intersection point into object's registrationPoint frame + var xformMat = Xform.mul(modelMatInv, intersectionMat); + + // convert to Mat4 + var offsetMat = Mat4.createFromRotAndTrans(xformMat.rot, xformMat.pos); + return offsetMat; +}; + + if (typeof module !== 'undefined') { module.exports = { makeDispatcherModuleParameters: makeDispatcherModuleParameters, @@ -508,6 +533,7 @@ if (typeof module !== 'undefined') { projectOntoEntityXYPlane: projectOntoEntityXYPlane, TRIGGER_OFF_VALUE: TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE: TRIGGER_ON_VALUE, - DISPATCHER_HOVERING_LIST: DISPATCHER_HOVERING_LIST + DISPATCHER_HOVERING_LIST: DISPATCHER_HOVERING_LIST, + worldPositionToRegistrationFrameMatrix: worldPositionToRegistrationFrameMatrix }; } From f81fe6b29f3998c4dbb1a941b38b7d93d7f2c7c3 Mon Sep 17 00:00:00 2001 From: David Back Date: Mon, 27 Aug 2018 16:35:36 -0700 Subject: [PATCH 127/545] add more inputs to controller mapping --- .../src/input-plugins/KeyboardMouseDevice.cpp | 2 + scripts/system/edit.js | 64 ++++++++++++------- 2 files changed, 42 insertions(+), 24 deletions(-) diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp index ddd51e9b9b..539546dd96 100755 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp @@ -304,6 +304,8 @@ controller::Input::NamedVector KeyboardMouseDevice::InputDevice::getAvailableInp availableInputs.append(Input::NamedPair(makeInput(Qt::Key_Control), "Control")); availableInputs.append(Input::NamedPair(makeInput(Qt::Key_Delete), "Delete")); availableInputs.append(Input::NamedPair(makeInput(Qt::Key_Backspace), QKeySequence(Qt::Key_Backspace).toString())); + availableInputs.append(Input::NamedPair(makeInput(Qt::Key_BracketLeft), "BracketLeft")); + availableInputs.append(Input::NamedPair(makeInput(Qt::Key_BracketRight), "BracketRight")); availableInputs.append(Input::NamedPair(makeInput(Qt::LeftButton), "LeftMouseButton")); availableInputs.append(Input::NamedPair(makeInput(Qt::MiddleButton), "MiddleMouseButton")); diff --git a/scripts/system/edit.js b/scripts/system/edit.js index 776c09addd..e145c1ab3d 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -1863,28 +1863,7 @@ var keyReleaseEvent = function (event) { cameraManager.keyReleaseEvent(event); } // since sometimes our menu shortcut keys don't work, trap our menu items here also and fire the appropriate menu items - if (event.text === 'd' && event.isControl) { - selectionManager.clearSelections(); - } else if (event.text === "t") { - selectionDisplay.toggleSpaceMode(); - } else if (event.text === "f") { - if (isActive) { - if (selectionManager.hasSelection()) { - cameraManager.enable(); - cameraManager.focus(selectionManager.worldPosition, - selectionManager.worldDimensions, - Menu.isOptionChecked(MENU_EASE_ON_FOCUS)); - } - } - } else if (event.text === '[') { - if (isActive) { - cameraManager.enable(); - } - } else if (event.text === 'g') { - if (isActive && selectionManager.hasSelection()) { - grid.moveToSelection(); - } - } else if (event.key === KEY_P && event.isControl && !event.isAutoRepeat ) { + if (event.key === KEY_P && event.isControl && !event.isAutoRepeat) { if (event.isShifted) { unparentSelectedEntities(); } else { @@ -1900,9 +1879,46 @@ function deleteKey(value) { deleteSelectedEntities(); } } +function deselectKey(value) { + if (value === 0) { // on release + selectionManager.clearSelections(); + } +} +function toggleKey(value) { + if (value === 0) { // on release + selectionDisplay.toggleSpaceMode(); + } +} +function focusKey(value) { + if (value === 0) { // on release + if (selectionManager.hasSelection()) { + cameraManager.enable(); + cameraManager.focus(selectionManager.worldPosition, + selectionManager.worldDimensions, + Menu.isOptionChecked(MENU_EASE_ON_FOCUS)); + } + } +} +function cameraKey(value) { + if (value === 0) { // on release + cameraManager.enable(); + } +} +function gridKey(value) { + if (value === 0) { // on release + if (selectionManager.hasSelection()) { + grid.moveToSelection(); + } + } +} var mapping = Controller.newMapping(CONTROLLER_MAPPING_NAME); -mapping.from([Controller.Hardware.Keyboard.Delete]).when([Controller.Hardware.Application.PlatformWindows]).peek().to(deleteKey); -mapping.from([Controller.Hardware.Keyboard.Backspace]).when([Controller.Hardware.Application.PlatformMac]).peek().to(deleteKey); +mapping.from([Controller.Hardware.Keyboard.Delete]).when([Controller.Hardware.Application.PlatformWindows]).to(deleteKey); +mapping.from([Controller.Hardware.Keyboard.Backspace]).when([Controller.Hardware.Application.PlatformMac]).to(deleteKey); +mapping.from([Controller.Hardware.Keyboard.D]).when([Controller.Hardware.Keyboard.Control]).to(deselectKey); +mapping.from([Controller.Hardware.Keyboard.T]).to(toggleKey); +mapping.from([Controller.Hardware.Keyboard.F]).to(focusKey); +mapping.from([Controller.Hardware.Keyboard.BracketLeft]).to(cameraKey); +mapping.from([Controller.Hardware.Keyboard.G]).to(gridKey); function recursiveAdd(newParentID, parentData) { if (parentData.children !== undefined) { From c19bd8968ad315df6abdfc336ba58fcafe47e041 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Mon, 27 Aug 2018 16:48:47 -0700 Subject: [PATCH 128/545] Fix mixer crash --- libraries/avatars/src/AvatarHashMap.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index 8dfee3551e..c437b56f32 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -239,7 +239,6 @@ AvatarSharedPointer AvatarHashMap::parseAvatarData(QSharedPointer Date: Mon, 27 Aug 2018 17:57:50 -0700 Subject: [PATCH 129/545] added some comment to explain rig to avatar transform --- interface/src/avatar/MyAvatar.cpp | 38 +++++++++++++++++-------------- interface/src/avatar/MyAvatar.h | 4 ++-- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index c4d855ee77..23feff88dd 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -453,13 +453,16 @@ void MyAvatar::update(float deltaTime) { // put the spine facing in sensor space. // then mix it with head facing to determine rotation recenter - glm::vec3 handHipAzimuthWorldSpace = transformVectorFast(getTransform().getMatrix(), glm::vec3(_hipToHandController.x, 0.0f, _hipToHandController.y)); - glm::mat4 sensorToWorldMat = getSensorToWorldMatrix(); - glm::mat4 worldToSensorMat = glm::inverse(sensorToWorldMat); - glm::vec3 handHipAzimuthSensorSpace = transformVectorFast(worldToSensorMat, glm::vec3(handHipAzimuthWorldSpace.x, 0.0f, handHipAzimuthWorldSpace.z)); - glm::vec2 normedHandHipAzimuthSensorSpace = glm::normalize(glm::vec2(handHipAzimuthSensorSpace.x, handHipAzimuthSensorSpace.z)); - glm::vec2 headFacingPlusHandHipAzimuthMix = lerp(normedHandHipAzimuthSensorSpace, _headControllerFacing, PERCENTAGE_WEIGHT_SHOULDERS_VS_HEAD_AZIMUTH); if (getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND).isValid() && getControllerPoseInAvatarFrame(controller::Action::RIGHT_HAND).isValid()) { + glm::vec3 handHipAzimuthWorldSpace = transformVectorFast(getTransform().getMatrix(), glm::vec3(_hipToHandController.x, 0.0f, _hipToHandController.y)); + glm::mat4 sensorToWorldMat = getSensorToWorldMatrix(); + glm::mat4 worldToSensorMat = glm::inverse(sensorToWorldMat); + glm::vec3 handHipAzimuthSensorSpace = transformVectorFast(worldToSensorMat, handHipAzimuthWorldSpace); + glm::vec2 normedHandHipAzimuthSensorSpace(0.0f, 1.0f); + if (glm::length(glm::vec2(handHipAzimuthSensorSpace.x, handHipAzimuthSensorSpace.z)) > 0.0f) { + normedHandHipAzimuthSensorSpace = glm::normalize(glm::vec2(handHipAzimuthSensorSpace.x, handHipAzimuthSensorSpace.z)); + } + glm::vec2 headFacingPlusHandHipAzimuthMix = lerp(normedHandHipAzimuthSensorSpace, _headControllerFacing, PERCENTAGE_WEIGHT_SHOULDERS_VS_HEAD_AZIMUTH); _headControllerFacingMovingAverage = lerp(_headControllerFacingMovingAverage, headFacingPlusHandHipAzimuthMix, tau); } else { _headControllerFacingMovingAverage = _headControllerFacing; @@ -475,7 +478,6 @@ void MyAvatar::update(float deltaTime) { _recentModeReadings.insert(newHeightReadingInCentimeters); setCurrentStandingHeight(computeStandingHeightMode(getControllerPoseInAvatarFrame(controller::Action::HEAD))); setAverageHeadRotation(computeAverageHeadRotation(getControllerPoseInAvatarFrame(controller::Action::HEAD))); - computeHandAzimuth(); #ifdef DEBUG_DRAW_HMD_MOVING_AVERAGE @@ -495,12 +497,8 @@ void MyAvatar::update(float deltaTime) { if (_goToPending) { setWorldPosition(_goToPosition); - setWorldOrientation(_goToOrientation); - if (getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND).isValid() && getControllerPoseInAvatarFrame(controller::Action::RIGHT_HAND).isValid()) { - _headControllerFacingMovingAverage = headFacingPlusHandHipAzimuthMix; - } else { - _headControllerFacingMovingAverage = _headControllerFacing; // reset moving average - } + setWorldOrientation(_goToOrientation); + _headControllerFacingMovingAverage = _headControllerFacing; _goToPending = false; // updateFromHMDSensorMatrix (called from paintGL) expects that the sensorToWorldMatrix is updated for any position changes // that happen between render and Application::update (which calls updateSensorToWorldMatrix to do so). @@ -827,15 +825,17 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { void MyAvatar::computeHandAzimuth() { auto leftHandPoseAvatarSpace = getLeftHandPose(); auto rightHandPoseAvatarSpace = getRightHandPose(); - glm::vec3 localLookat(0.0f, 0.0f, 1.0f); const float HALFWAY = 0.50f; if (leftHandPoseAvatarSpace.isValid() && rightHandPoseAvatarSpace.isValid()) { // we need the old azimuth reading to prevent flipping the facing direction 180 // in the case where the hands go from being slightly less than 180 apart to slightly more than 180 apart. vec2 oldAzimuthReading = _hipToHandController; - _hipToHandController = lerp(glm::normalize(glm::vec2(rightHandPoseAvatarSpace.translation.x, rightHandPoseAvatarSpace.translation.z)), glm::normalize(glm::vec2(leftHandPoseAvatarSpace.translation.x, leftHandPoseAvatarSpace.translation.z)), HALFWAY); - + if ((glm::length(glm::vec2(rightHandPoseAvatarSpace.translation.x, rightHandPoseAvatarSpace.translation.z)) > 0.0f) && (glm::length(glm::vec2(leftHandPoseAvatarSpace.translation.x, leftHandPoseAvatarSpace.translation.z)) > 0.0f)) { + _hipToHandController = lerp(glm::normalize(glm::vec2(rightHandPoseAvatarSpace.translation.x, rightHandPoseAvatarSpace.translation.z)), glm::normalize(glm::vec2(leftHandPoseAvatarSpace.translation.x, leftHandPoseAvatarSpace.translation.z)), HALFWAY); + } else { + _hipToHandController = glm::vec2(0.0f, 1.0f); + } // check the angular distance from forward and back float cosForwardAngle = glm::dot(_hipToHandController, oldAzimuthReading); float cosBackwardAngle = glm::dot(_hipToHandController, -oldAzimuthReading); @@ -3376,7 +3376,11 @@ glm::mat4 MyAvatar::deriveBodyFromHMDSensor() const { glm::mat4 MyAvatar::getSpine2RotationRigSpace() const { static const glm::quat RIG_CHANGE_OF_BASIS = Quaternions::Y_180; - glm::vec3 hipToHandRigSpace = RIG_CHANGE_OF_BASIS * glm::vec3(_hipToHandController.x, 0.0f, _hipToHandController.y); + // RIG_CHANGE_OF_BASIS * INITIAL_RIG_ROTATION * Quaternions::IDENTITY(explicit rig rotation) * inverse(RIG_CHANGE_OF_BASIS) = Quaternions::Y_180(avatar Space); + // INITIAL_RIG_ROTATION = Quaternions::Y_180; + static const glm::quat INITIAL_RIG_ROTATION = Quaternions::Y_180; + glm::quat avatarToRigSpace = INITIAL_RIG_ROTATION * Quaternions::IDENTITY; + glm::vec3 hipToHandRigSpace = avatarToRigSpace * glm::vec3(_hipToHandController.x, 0.0f, _hipToHandController.y); glm::vec3 u, v, w; generateBasisVectors(glm::vec3(0.0f,1.0f,0.0f), hipToHandRigSpace, u, v, w); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index f819c417de..8cccb03ea5 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -285,7 +285,7 @@ public: Q_INVOKABLE void centerBody(); // thread-safe - /**jsdoc_hmdSensorMatrix + /**jsdoc * The internal inverse-kinematics system maintains a record of which joints are "locked". Sometimes it is useful to forget this history, to prevent * contorted joints. * @function MyAvatar.clearIKJointLimitHistory @@ -1650,7 +1650,7 @@ private: std::atomic _hasScriptedBlendShapes { false }; std::atomic _rotationRecenterFilterLength { 4.0f }; std::atomic _rotationThreshold { 0.5235f }; // 30 degrees in radians - std::atomic _stepResetRotationEnabled { false }; + std::atomic _stepResetRotationEnabled { true }; std::atomic _drawAverageFacingEnabled { false }; // working copy -- see AvatarData for thread-safe _sensorToWorldMatrixCache, used for outward facing access From 511478a563841ec944121c967bbc219409ea9874 Mon Sep 17 00:00:00 2001 From: David Back Date: Mon, 27 Aug 2018 18:11:19 -0700 Subject: [PATCH 130/545] use not Mac instead of Windows --- scripts/system/edit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/edit.js b/scripts/system/edit.js index e145c1ab3d..dd53e8c395 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -1912,7 +1912,7 @@ function gridKey(value) { } } var mapping = Controller.newMapping(CONTROLLER_MAPPING_NAME); -mapping.from([Controller.Hardware.Keyboard.Delete]).when([Controller.Hardware.Application.PlatformWindows]).to(deleteKey); +mapping.from([Controller.Hardware.Keyboard.Delete]).when([!Controller.Hardware.Application.PlatformMac]).to(deleteKey); mapping.from([Controller.Hardware.Keyboard.Backspace]).when([Controller.Hardware.Application.PlatformMac]).to(deleteKey); mapping.from([Controller.Hardware.Keyboard.D]).when([Controller.Hardware.Keyboard.Control]).to(deselectKey); mapping.from([Controller.Hardware.Keyboard.T]).to(toggleKey); From 63eb57c741c352e86caaa59515e203a3e8f6e13c Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 28 Aug 2018 08:58:25 -0700 Subject: [PATCH 131/545] Exploring PID again --- interface/src/LODManager.cpp | 73 +++++++++++++++++++--- interface/src/LODManager.h | 21 ++++++- libraries/render/src/render/Args.h | 2 + scripts/developer/utilities/render/lod.qml | 53 ++++++++++++++++ 4 files changed, 140 insertions(+), 9 deletions(-) diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index cd692bccf0..91a547cf31 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -75,9 +75,41 @@ void LODManager::autoAdjustLOD(float realTimeDelta) { return; } + auto Kp = _pid.x; + auto Ki = _pid.y; + auto Kd = _pid.z; + float oldOctreeSizeScale = _octreeSizeScale; + float oldSolidAngle = getSolidAngle(); + + float targetFPS = getLODDecreaseFPS(); + float targetPeriod = 1.0f / targetFPS; + float currentFPS = (float)MSECS_PER_SECOND / _avgRenderTime; + static uint64_t lastTime = usecTimestampNow(); uint64_t now = usecTimestampNow(); + auto dt = (float) ((now - lastTime) / double(USECS_PER_MSEC)); + if (dt < targetPeriod * _pid.w) return; + + float deltaFPS = currentFPS - getLODDecreaseFPS(); + + lastTime = now; + auto previous_error = 0.f; + auto integral = 0.f; + + auto error = getLODDecreaseFPS() - currentFPS; + integral = integral + error * dt; + auto derivative = (error - previous_error) / dt; + auto output = Kp * error + Ki * integral + Kd * derivative; + previous_error = error; + + auto newSolidAngle = std::max( 0.1f, std::min(output, 45.f)); + + auto halTan = glm::tan(glm::radians(newSolidAngle * 0.5f)); + + auto octreeSizeScale = TREE_SCALE * OCTREE_TO_MESH_RATIO / halTan; + _octreeSizeScale = octreeSizeScale; +/* if (currentFPS < getLODDecreaseFPS()) { if (now > _decreaseFPSExpiry) { _decreaseFPSExpiry = now + LOD_AUTO_ADJUST_PERIOD; @@ -123,7 +155,7 @@ void LODManager::autoAdjustLOD(float realTimeDelta) { _increaseFPSExpiry = now + LOD_AUTO_ADJUST_PERIOD; _decreaseFPSExpiry = _increaseFPSExpiry; } - +*/ if (oldOctreeSizeScale != _octreeSizeScale) { auto lodToolsDialog = DependencyManager::get()->getLodToolsDialog(); if (lodToolsDialog) { @@ -243,7 +275,7 @@ bool LODManager::shouldRender(const RenderArgs* args, const AABox& bounds) { auto pos = args->getViewFrustum().getPosition() - bounds.calcCenter(); auto dim = bounds.getDimensions(); auto halfTanSq = 0.25f * glm::dot(dim, dim) / glm::dot(pos, pos); - return (halfTanSq >= args->_solidAngleHalfTan * args->_solidAngleHalfTan); + return (halfTanSq >= args->_solidAngleHalfTanSq); }; @@ -279,10 +311,10 @@ void LODManager::setWorldDetailQuality(float quality) { bool isHMDMode = qApp->isHMDMode(); float maxFPS = isHMDMode ? MAX_HMD_FPS : MAX_DESKTOP_FPS; - float desiredFPS = maxFPS - THRASHING_DIFFERENCE; + float desiredFPS = maxFPS /* - THRASHING_DIFFERENCE*/; if (!isLowestValue) { - float calculatedFPS = (maxFPS - (maxFPS * quality)) - THRASHING_DIFFERENCE; + float calculatedFPS = (maxFPS - (maxFPS * quality))/* - THRASHING_DIFFERENCE*/; desiredFPS = calculatedFPS < MIN_FPS ? MIN_FPS : calculatedFPS; } @@ -315,14 +347,15 @@ float LODManager::getWorldDetailQuality() const { increaseFPS = getDesktopLODDecreaseFPS(); } float maxFPS = inHMD ? MAX_HMD_FPS : MAX_DESKTOP_FPS; - float percentage = increaseFPS / maxFPS; + float percentage = 1.0 - increaseFPS / maxFPS; - if (percentage >= HIGH) { + if (percentage <= LOW) { return LOW; } - else if (percentage >= LOW) { + else if (percentage <= MEDIUM) { return MEDIUM; } + return HIGH; } @@ -334,3 +367,29 @@ float LODManager::getSolidAngleHalfTan() const { float LODManager::getSolidAngle() const { return glm::degrees(2.0 * atan(getSolidAngleHalfTan())); } + + +float LODManager::getPidKp() const { + return _pid.x; +} +float LODManager::getPidKi() const { + return _pid.y; +} +float LODManager::getPidKd() const { + return _pid.z; +} +float LODManager::getPidT() const { + return _pid.w; +} +void LODManager::setPidKp(float k) { + _pid.x = k; +} +void LODManager::setPidKi(float k) { + _pid.y = k; +} +void LODManager::setPidKd(float k) { + _pid.z = k; +} +void LODManager::setPidT(float t) { + _pid.w = t; +} diff --git a/interface/src/LODManager.h b/interface/src/LODManager.h index 340292c579..2251281ae2 100644 --- a/interface/src/LODManager.h +++ b/interface/src/LODManager.h @@ -23,8 +23,8 @@ const float DEFAULT_DESKTOP_LOD_DOWN_FPS = 30.0f; const float DEFAULT_HMD_LOD_DOWN_FPS = 34.0f; const float DEFAULT_DESKTOP_MAX_RENDER_TIME = (float)MSECS_PER_SECOND / DEFAULT_DESKTOP_LOD_DOWN_FPS; // msec const float DEFAULT_HMD_MAX_RENDER_TIME = (float)MSECS_PER_SECOND / DEFAULT_HMD_LOD_DOWN_FPS; // msec -const float MAX_LIKELY_DESKTOP_FPS = 59.0f; // this is essentially, V-synch - 1 fps -const float MAX_LIKELY_HMD_FPS = 74.0f; // this is essentially, V-synch - 1 fps +const float MAX_LIKELY_DESKTOP_FPS = 61.0f; // this is essentially, V-synch - 1 fps +const float MAX_LIKELY_HMD_FPS = 91.0f; // this is essentially, V-synch - 1 fps const float INCREASE_LOD_GAP_FPS = 10.0f; // fps // The default value DEFAULT_OCTREE_SIZE_SCALE means you can be 400 meters away from a 1 meter object in order to see it (which is ~20:20 vision). @@ -72,6 +72,12 @@ class LODManager : public QObject, public Dependency { Q_PROPERTY(float solidAngleHalfTan READ getSolidAngleHalfTan) Q_PROPERTY(float solidAngle READ getSolidAngle) + Q_PROPERTY(float pidKp READ getPidKp WRITE setPidKp) + Q_PROPERTY(float pidKi READ getPidKi WRITE setPidKi) + Q_PROPERTY(float pidKd READ getPidKd WRITE setPidKd) + Q_PROPERTY(float pidT READ getPidT WRITE setPidT) + + public: /**jsdoc @@ -190,6 +196,15 @@ public: float getSolidAngleHalfTan() const; float getSolidAngle() const; + float getPidKp() const; + float getPidKi() const; + float getPidKd() const; + float getPidT() const; + void setPidKp(float k); + void setPidKi(float k); + void setPidKd(float k); + void setPidT(float t); + signals: /**jsdoc @@ -222,6 +237,8 @@ private: float _octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE; int _boundaryLevelAdjust = 0; + glm::vec4 _pid{ 0.1f, 0.0f, 0.0f, 3.0f }; + uint64_t _decreaseFPSExpiry { 0 }; uint64_t _increaseFPSExpiry { 0 }; }; diff --git a/libraries/render/src/render/Args.h b/libraries/render/src/render/Args.h index a46b914826..589945e9c7 100644 --- a/libraries/render/src/render/Args.h +++ b/libraries/render/src/render/Args.h @@ -81,6 +81,7 @@ namespace render { _context(context), _sizeScale(sizeScale), _solidAngleHalfTan(solidAngleHalfTan), + _solidAngleHalfTanSq(solidAngleHalfTan * solidAngleHalfTan), _boundaryLevelAdjust(boundaryLevelAdjust), _renderMode(renderMode), _displayMode(displayMode), @@ -111,6 +112,7 @@ namespace render { float _sizeScale { 1.0f }; int _boundaryLevelAdjust { 0 }; float _solidAngleHalfTan{ 0.1f }; + float _solidAngleHalfTanSq{ _solidAngleHalfTan * _solidAngleHalfTan }; RenderMode _renderMode { DEFAULT_RENDER_MODE }; DisplayMode _displayMode { MONO }; diff --git a/scripts/developer/utilities/render/lod.qml b/scripts/developer/utilities/render/lod.qml index c08c089bad..742e8c0dc1 100644 --- a/scripts/developer/utilities/render/lod.qml +++ b/scripts/developer/utilities/render/lod.qml @@ -78,6 +78,59 @@ Item { anchors.left: parent.left anchors.right: parent.right } + + RichSlider { + visible: LODManager.automaticLODAdjust + showLabel: true + label: "LOD PID Kp" + valueVar: LODManager["pidKp"] + valueVarSetter: (function (v) { LODManager["pidKp"] = v }) + max: 1.0 + min: 0.0 + integral: false + + anchors.left: parent.left + anchors.right: parent.right + } + RichSlider { + visible: LODManager.automaticLODAdjust + showLabel: true + label: "LOD PID Ki" + valueVar: LODManager["pidKi"] + valueVarSetter: (function (v) { LODManager["pidKi"] = v }) + max: 1.0 + min: 0.0 + integral: false + + anchors.left: parent.left + anchors.right: parent.right + } + RichSlider { + visible: LODManager.automaticLODAdjust + showLabel: true + label: "LOD PID Kd" + valueVar: LODManager["pidKd"] + valueVarSetter: (function (v) { LODManager["pidKd"] = v }) + max: 1.0 + min: 0.0 + integral: false + + anchors.left: parent.left + anchors.right: parent.right + } + RichSlider { + visible: LODManager.automaticLODAdjust + showLabel: true + label: "LOD PID Num T" + valueVar: LODManager["pidT"] + valueVarSetter: (function (v) { LODManager["pidT"] = v }) + max: 5.0 + min: 0.0 + integral: false + + anchors.left: parent.left + anchors.right: parent.right + } } Column { From 027d11736446769867807294f6e842463ee4889a Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Tue, 28 Aug 2018 09:41:09 -0700 Subject: [PATCH 132/545] Remove deadlock caused by trying readlock on NodeList Also just use refs to other SharedNodes as the NodeList is locked. --- assignment-client/src/avatars/AvatarMixerSlave.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index 2ba54bd6b6..50ddcec92b 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -288,13 +288,19 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // setup list of AvatarData as well as maps to map betweeen the AvatarData and the original nodes struct AvatarSortData { - SharedNodePointer _nodeShared; + AvatarSortData(const SharedNodePointer& nodeShared, AvatarData* avatarData, quint64 lastEncodeTime) + : _nodeShared(nodeShared) + , _node(nodeShared.data()) + , _avatarData(avatarData) + , _lastEncodeTime(lastEncodeTime) + { } + const SharedNodePointer& _nodeShared; Node* _node; AvatarData* _avatarData; quint64 _lastEncodeTime; }; + // Temporary info about the avatars we're sending: std::vector avatarsToSort; - avatarsToSort.reserve(nodeList->size()); //std::unordered_map avatarDataToNodes; //std::unordered_map avatarDataToNodesShared; //std::unordered_map avatarEncodeTimes; @@ -311,7 +317,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) //avatarDataToNodes[otherAvatar] = otherNode.data(); //avatarDataToNodesShared[otherAvatar] = otherNode; auto lastEncodeTime = nodeData->getLastOtherAvatarEncodeTime(otherAvatar->getSessionUUID()); - avatarsToSort.emplace_back(AvatarSortData({ otherNode, otherNodeRaw, otherAvatar, lastEncodeTime })); + avatarsToSort.emplace_back(AvatarSortData(otherNode, otherAvatar, lastEncodeTime)); } }); @@ -345,7 +351,6 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) AvatarData::_avatarSortCoefficientAge); // ignore or sort - const AvatarData* thisAvatar = nodeData->getAvatarSharedPointer().get(); for (const auto& avatar : avatarsToSort) { if (avatar._node == nodeRaw) { // don't echo updates to self @@ -437,7 +442,6 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) int remainingAvatars = (int)sortedAvatars.size(); auto traitsPacketList = NLPacketList::create(PacketType::BulkAvatarTraits, QByteArray(), true, true); while (!sortedAvatars.empty()) { - const AvatarData* avatarData = sortedAvatars.top().getAvatar(); const Node* otherNode = sortedAvatars.top().getNode(); sortedAvatars.pop(); remainingAvatars--; From c4d43b3fbc5238ff50838faba1e02ea6d0f4df41 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Tue, 28 Aug 2018 19:43:59 +0200 Subject: [PATCH 133/545] CR fixes --- interface/resources/qml/InteractiveWindow.qml | 2 +- libraries/ui/src/MainWindow.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/InteractiveWindow.qml b/interface/resources/qml/InteractiveWindow.qml index 1c41dd189b..e8ddbf823d 100644 --- a/interface/resources/qml/InteractiveWindow.qml +++ b/interface/resources/qml/InteractiveWindow.qml @@ -147,7 +147,7 @@ Windows.Window { Qt.WindowMaximizeButtonHint | Qt.WindowMinimizeButtonHint; // only use the always on top feature for non Windows OS - if (Qt.platform.os !== "windows" && (flags & Desktop.ALWAYS_ON_TOP) === Desktop.ALWAYS_ON_TOP) { + if (Qt.platform.os !== "windows" && (flags & Desktop.ALWAYS_ON_TOP)) { nativeWindowFlags |= Qt.WindowStaysOnTopHint; } nativeWindow.flags = nativeWindowFlags; diff --git a/libraries/ui/src/MainWindow.cpp b/libraries/ui/src/MainWindow.cpp index 1a13194974..680433b2f9 100644 --- a/libraries/ui/src/MainWindow.cpp +++ b/libraries/ui/src/MainWindow.cpp @@ -43,7 +43,7 @@ MainWindow::~MainWindow() { QWindow* MainWindow::findMainWindow() { auto windows = qApp->topLevelWindows(); QWindow* result = nullptr; - for (auto window : windows) { + for (const auto& window : windows) { if (window->objectName().contains("MainWindow")) { result = window; break; From 3c792a04c1dfe8096ab789ed0b146d50d4f31c89 Mon Sep 17 00:00:00 2001 From: amantley Date: Tue, 28 Aug 2018 11:25:42 -0700 Subject: [PATCH 134/545] fixed roll rotation added to azimuth in MySkeletonModel.cpp --- interface/src/avatar/MyAvatar.cpp | 35 +-- interface/src/avatar/MyAvatar.h | 2 + interface/src/avatar/MySkeletonModel.cpp | 33 +- scripts/developer/rotateApp.js | 385 ----------------------- 4 files changed, 38 insertions(+), 417 deletions(-) delete mode 100644 scripts/developer/rotateApp.js diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 23feff88dd..32822fc1b9 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -447,12 +447,12 @@ void MyAvatar::reset(bool andRecenter, bool andReload, bool andHead) { void MyAvatar::update(float deltaTime) { // update moving average of HMD facing in xz plane. const float HMD_FACING_TIMESCALE = getRotationRecenterFilterLength(); - const float PERCENTAGE_WEIGHT_SHOULDERS_VS_HEAD_AZIMUTH = 0.0f; // 100 percent shoulders + const float PERCENTAGE_WEIGHT_HEAD_VS_SHOULDERS_AZIMUTH = 0.0f; // 100 percent shoulders float tau = deltaTime / HMD_FACING_TIMESCALE; - // put the spine facing in sensor space. - // then mix it with head facing to determine rotation recenter + // put the average hand azimuth into sensor space. + // then mix it with head facing direction to determine rotation recenter if (getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND).isValid() && getControllerPoseInAvatarFrame(controller::Action::RIGHT_HAND).isValid()) { glm::vec3 handHipAzimuthWorldSpace = transformVectorFast(getTransform().getMatrix(), glm::vec3(_hipToHandController.x, 0.0f, _hipToHandController.y)); glm::mat4 sensorToWorldMat = getSensorToWorldMatrix(); @@ -462,7 +462,7 @@ void MyAvatar::update(float deltaTime) { if (glm::length(glm::vec2(handHipAzimuthSensorSpace.x, handHipAzimuthSensorSpace.z)) > 0.0f) { normedHandHipAzimuthSensorSpace = glm::normalize(glm::vec2(handHipAzimuthSensorSpace.x, handHipAzimuthSensorSpace.z)); } - glm::vec2 headFacingPlusHandHipAzimuthMix = lerp(normedHandHipAzimuthSensorSpace, _headControllerFacing, PERCENTAGE_WEIGHT_SHOULDERS_VS_HEAD_AZIMUTH); + glm::vec2 headFacingPlusHandHipAzimuthMix = lerp(normedHandHipAzimuthSensorSpace, _headControllerFacing, PERCENTAGE_WEIGHT_HEAD_VS_SHOULDERS_AZIMUTH); _headControllerFacingMovingAverage = lerp(_headControllerFacingMovingAverage, headFacingPlusHandHipAzimuthMix, tau); } else { _headControllerFacingMovingAverage = _headControllerFacing; @@ -497,7 +497,7 @@ void MyAvatar::update(float deltaTime) { if (_goToPending) { setWorldPosition(_goToPosition); - setWorldOrientation(_goToOrientation); + setWorldOrientation(_goToOrientation); _headControllerFacingMovingAverage = _headControllerFacing; _goToPending = false; // updateFromHMDSensorMatrix (called from paintGL) expects that the sensorToWorldMatrix is updated for any position changes @@ -834,15 +834,14 @@ void MyAvatar::computeHandAzimuth() { if ((glm::length(glm::vec2(rightHandPoseAvatarSpace.translation.x, rightHandPoseAvatarSpace.translation.z)) > 0.0f) && (glm::length(glm::vec2(leftHandPoseAvatarSpace.translation.x, leftHandPoseAvatarSpace.translation.z)) > 0.0f)) { _hipToHandController = lerp(glm::normalize(glm::vec2(rightHandPoseAvatarSpace.translation.x, rightHandPoseAvatarSpace.translation.z)), glm::normalize(glm::vec2(leftHandPoseAvatarSpace.translation.x, leftHandPoseAvatarSpace.translation.z)), HALFWAY); } else { - _hipToHandController = glm::vec2(0.0f, 1.0f); + _hipToHandController = glm::vec2(0.0f, -1.0f); } // check the angular distance from forward and back float cosForwardAngle = glm::dot(_hipToHandController, oldAzimuthReading); float cosBackwardAngle = glm::dot(_hipToHandController, -oldAzimuthReading); // if we are now closer to the 180 flip of the previous chest forward - // then we negate our computed _hipToHandController to keep the chest in the same direction. + // then we negate our computed _hipToHandController to keep the chest from flipping. if (cosBackwardAngle > cosForwardAngle) { - // this means we have lost continuity with the current chest position _hipToHandController = -_hipToHandController; } } @@ -3375,12 +3374,10 @@ glm::mat4 MyAvatar::deriveBodyFromHMDSensor() const { glm::mat4 MyAvatar::getSpine2RotationRigSpace() const { - static const glm::quat RIG_CHANGE_OF_BASIS = Quaternions::Y_180; - // RIG_CHANGE_OF_BASIS * INITIAL_RIG_ROTATION * Quaternions::IDENTITY(explicit rig rotation) * inverse(RIG_CHANGE_OF_BASIS) = Quaternions::Y_180(avatar Space); - // INITIAL_RIG_ROTATION = Quaternions::Y_180; - static const glm::quat INITIAL_RIG_ROTATION = Quaternions::Y_180; - glm::quat avatarToRigSpace = INITIAL_RIG_ROTATION * Quaternions::IDENTITY; - glm::vec3 hipToHandRigSpace = avatarToRigSpace * glm::vec3(_hipToHandController.x, 0.0f, _hipToHandController.y); + // static const glm::quat RIG_CHANGE_OF_BASIS = Quaternions::Y_180; + // RIG_CHANGE_OF_BASIS * AVATAR_TO_RIG_ROTATION * inverse(RIG_CHANGE_OF_BASIS) = Quaternions::Y_180; //avatar Space; + const glm::quat AVATAR_TO_RIG_ROTATION = Quaternions::Y_180; + glm::vec3 hipToHandRigSpace = AVATAR_TO_RIG_ROTATION * glm::vec3(_hipToHandController.x, 0.0f, _hipToHandController.y); glm::vec3 u, v, w; generateBasisVectors(glm::vec3(0.0f,1.0f,0.0f), hipToHandRigSpace, u, v, w); @@ -3971,7 +3968,7 @@ bool MyAvatar::FollowHelper::shouldActivateHorizontalCG(MyAvatar& myAvatar) cons glm::vec3 currentHeadPosition = currentHeadPose.getTranslation(); float anatomicalHeadToHipsDistance = glm::length(defaultHeadPosition - defaultHipsPosition); if (!isActive(Horizontal) && - (glm::length(currentHeadPosition - defaultHipsPosition) > (anatomicalHeadToHipsDistance + (DEFAULT_AVATAR_SPINE_STRETCH_LIMIT * anatomicalHeadToHipsDistance * myAvatar.getAvatarScale())))) { + (glm::length(currentHeadPosition - defaultHipsPosition) > (anatomicalHeadToHipsDistance + (DEFAULT_AVATAR_SPINE_STRETCH_LIMIT * anatomicalHeadToHipsDistance)))) { myAvatar.setResetMode(true); stepDetected = true; } @@ -3995,14 +3992,14 @@ void MyAvatar::FollowHelper::prePhysicsUpdate(MyAvatar& myAvatar, const glm::mat qApp->getCamera().getMode() != CAMERA_MODE_MIRROR) { if (!isActive(Rotation) && (shouldActivateRotation(myAvatar, desiredBodyMatrix, currentBodyMatrix) || hasDriveInput)) { activate(Rotation); - myAvatar.setHeadControllerFacingMovingAverage(myAvatar._headControllerFacing); + myAvatar.setHeadControllerFacingMovingAverage(myAvatar.getHeadControllerFacing()); } if (myAvatar.getCenterOfGravityModelEnabled()) { if (!isActive(Horizontal) && (shouldActivateHorizontalCG(myAvatar) || hasDriveInput)) { activate(Horizontal); if (myAvatar.getEnableStepResetRotation()) { activate(Rotation); - myAvatar.setHeadControllerFacingMovingAverage(myAvatar._headControllerFacing); + myAvatar.setHeadControllerFacingMovingAverage(myAvatar.getHeadControllerFacing()); } } } else { @@ -4010,7 +4007,7 @@ void MyAvatar::FollowHelper::prePhysicsUpdate(MyAvatar& myAvatar, const glm::mat activate(Horizontal); if (myAvatar.getEnableStepResetRotation()) { activate(Rotation); - myAvatar.setHeadControllerFacingMovingAverage(myAvatar._headControllerFacing); + myAvatar.setHeadControllerFacingMovingAverage(myAvatar.getHeadControllerFacing()); } } } @@ -4020,7 +4017,7 @@ void MyAvatar::FollowHelper::prePhysicsUpdate(MyAvatar& myAvatar, const glm::mat } else { if (!isActive(Rotation) && getForceActivateRotation()) { activate(Rotation); - myAvatar.setHeadControllerFacingMovingAverage(myAvatar._headControllerFacing); + myAvatar.setHeadControllerFacingMovingAverage(myAvatar.getHeadControllerFacing()); setForceActivateRotation(false); } if (!isActive(Horizontal) && getForceActivateHorizontal()) { diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 8cccb03ea5..8b5d9d8c55 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -914,6 +914,8 @@ public: virtual void rebuildCollisionShape() override; + const glm::vec2& getHipToHandController() const { return _hipToHandController; } + void setHipToHandController(glm::vec2 currentHipToHandController) { _hipToHandController = currentHipToHandController; } const glm::vec2& getHeadControllerFacing() const { return _headControllerFacing; } void setHeadControllerFacing(glm::vec2 currentHeadControllerFacing) { _headControllerFacing = currentHeadControllerFacing; } const glm::vec2& getHeadControllerFacingMovingAverage() const { return _headControllerFacingMovingAverage; } diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index f150379f0c..e06a06cf0e 100644 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -239,21 +239,28 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { params.primaryControllerFlags[Rig::PrimaryControllerType_Hips] = (uint8_t)Rig::ControllerFlags::Enabled | (uint8_t)Rig::ControllerFlags::Estimated; // set spine2 if we have hand controllers - AnimPose currentPose; - bool ret = _rig.getAbsoluteJointPoseInRigFrame(_rig.indexOfJoint("Spine2"),currentPose); - AnimPose rigSpaceYaw(myAvatar->getSpine2RotationRigSpace()); - glm::vec3 u, v, w; - glm::vec3 fwd = rigSpaceYaw.rot() * glm::vec3(0.0f, 0.0f, 1.0f); - glm::vec3 up = currentPose.rot() * glm::vec3(0.0f, 1.0f, 0.0f); - generateBasisVectors(up, fwd, u, v, w); - AnimPose newSpinePose(glm::mat4(glm::vec4(w, 0.0f), glm::vec4(u, 0.0f), glm::vec4(v, 0.0f), glm::vec4(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f))); - if (myAvatar->getControllerPoseInAvatarFrame(controller::Action::RIGHT_HAND).isValid() && myAvatar->getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND).isValid()) { - AnimPose newSpinePose(myAvatar->getSpine2RotationRigSpace()); - currentPose.rot() = newSpinePose.rot(); + AnimPose currentSpine2Pose; + AnimPose currentHeadPose; + AnimPose currentHipsPose; + bool ret = _rig.getAbsoluteJointPoseInRigFrame(_rig.indexOfJoint("Spine2"), currentSpine2Pose); + bool ret1 = _rig.getAbsoluteJointPoseInRigFrame(_rig.indexOfJoint("Head"), currentHeadPose); + bool ret2 = _rig.getAbsoluteJointPoseInRigFrame(_rig.indexOfJoint("Hips"), currentHipsPose); + AnimPose rigSpaceYaw(myAvatar->getSpine2RotationRigSpace()); + glm::vec3 u, v, w; + glm::vec3 fwd = rigSpaceYaw.rot() * glm::vec3(0.0f, 0.0f, 1.0f); + glm::vec3 up = currentHeadPose.trans() - currentHipsPose.trans(); + if (glm::length(up) > 0.0f) { + up = glm::normalize(up); + } else { + up = glm::vec3(0.0f, 1.0f, 0.0f); + } + generateBasisVectors(up, fwd, u, v, w); + AnimPose newSpinePose(glm::mat4(glm::vec4(w, 0.0f), glm::vec4(u, 0.0f), glm::vec4(v, 0.0f), glm::vec4(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f))); + currentSpine2Pose.rot() = newSpinePose.rot(); + params.primaryControllerPoses[Rig::PrimaryControllerType_Spine2] = currentSpine2Pose; + params.primaryControllerFlags[Rig::PrimaryControllerType_Spine2] = (uint8_t)Rig::ControllerFlags::Enabled | (uint8_t)Rig::ControllerFlags::Estimated; } - params.primaryControllerPoses[Rig::PrimaryControllerType_Spine2] = currentPose; - params.primaryControllerFlags[Rig::PrimaryControllerType_Spine2] = (uint8_t)Rig::ControllerFlags::Enabled | (uint8_t)Rig::ControllerFlags::Estimated; } else { _prevHipsValid = false; diff --git a/scripts/developer/rotateApp.js b/scripts/developer/rotateApp.js deleted file mode 100644 index 030385b6fb..0000000000 --- a/scripts/developer/rotateApp.js +++ /dev/null @@ -1,385 +0,0 @@ -/* global Script, Vec3, MyAvatar, Tablet, Messages, Quat, -DebugDraw, Mat4, Entities, Xform, Controller, Camera, console, document*/ - -Script.registerValue("ROTATEAPP", true); - -var TABLET_BUTTON_NAME = "ROTATE"; -var CHANGE_OF_BASIS_ROTATION = { x: 0, y: 1, z: 0, w: 0 }; -var DEFAULT_HEAD_TURN_THRESHOLD = 0.5333; -var DEFAULT_HEAD_TURN_FILTER_LENGTH = 4.0; -var LOADING_DELAY = 2000; -var AVERAGING_RATE = 0.03; -var INCREASING = 1.0; -var DECREASING = -1.0; -var DEGREES_PER_PI_RADIANS = 180.0; -var FILTER_FUDGE_RANGE = 0.9; - -var activated = false; -var documentLoaded = false; -var sciptLoaded = false; -var headPoseAverageOrientation = { x: 0, y: 0, z: 0, w: 1 }; -var hipToLeftHandAverage = 0.0; // { x: 0, y: 0, z: 0, w: 1 }; -var hipToRightHandAverage = 0.0; // { x: 0, y: 0, z: 0, w: 1 }; -var averageAzimuth = 0.0; -var hipsPositionRigSpace = { x: 0, y: 0, z: 0 }; -var spine2PositionRigSpace = { x: 0, y: 0, z: 0 }; -var hipsRotationRigSpace = { x: 0, y: 0, z: 0, w: 1 }; -var spine2RotationRigSpace = { x: 0, y: 0, z: 0, w: 1 }; -var spine2Rotation = { x: 0, y: 0, z: 0, w: 1 }; -var hipToLHandAverage = { x: 0, y: 0, z: 0, w: 1 }; -var hipToRHandAverage = { x: 0, y: 0, z: 0, w: 1 }; - -/* -var ikTypes = { - RotationAndPosition: 0, - RotationOnly: 1, - HmdHead: 2, - HipsRelativeRotationAndPosition: 3, - Spline: 4, - Unknown: 5 -}; - - -var ANIM_VARS = [ - //"headType", - "spine2Type", - //"hipsType", - "spine2Position", - "spine2Rotation" - //"hipsPosition", - //"hipsRotation" -]; - -var handlerId = MyAvatar.addAnimationStateHandler(function (props) { - //print("in callback"); - //print("props spine2 pos: " + props.spine2Position.x + " " + props.spine2Position.y + " " + props.spine2Position.z); - //print("props hip pos: " + props.hipsPosition.x + " " + props.hipsPosition.y + " " + props.hipsPosition.z); - var result = {}; - //{x:0,y:0,z:0} - //result.headType = ikTypes.HmdHead; - //result.hipsType = ikTypes.RotationAndPosition; - //result.hipsPosition = hipsPositionRigSpace; // { x: 0, y: 0, z: 0 }; - //result.hipsRotation = hipsRotationRigSpace;//{ x: 0, y: 0, z: 0, w: 1 }; // - result.spine2Type = ikTypes.Spline; - result.spine2Position = spine2PositionRigSpace; // { x: 0, y: 1.3, z: 0 }; - result.spine2Rotation = spine2Rotation; - - return result; -}, ANIM_VARS); -*/ -// define state readings constructor -function StateReading(headPose, rhandPose, lhandPose, diffFromAverageEulers) { - this.headPose = headPose; - this.rhandPose = rhandPose; - this.lhandPose = lhandPose; - this.diffFromAverageEulers = diffFromAverageEulers; -} - -// define current state readings object for holding tracker readings and current differences from averages -var currentStateReadings = new StateReading(Controller.getPoseValue(Controller.Standard.Head), - Controller.getPoseValue(Controller.Standard.RightHand), - Controller.getPoseValue(Controller.Standard.LeftHand), - { x: 0, y: 0, z: 0 }); - -// declare the checkbox constructor -function AppCheckbox(type,id,eventType,isChecked) { - this.type = type; - this.id = id; - this.eventType = eventType; - this.data = {value: isChecked}; -} - -var usingStepResetRotationDirection = new AppCheckbox("checkboxtick", "stepReset", "onStepResetCheckBox", false); -var usingDrawAverageFacing = new AppCheckbox("checkboxtick", "drawAverage", "onDrawAverageFacingCheckBox", false); -var checkBoxArray = new Array(usingStepResetRotationDirection, usingDrawAverageFacing); - -// declare the html slider constructor -function AppProperty(name, type, eventType, signalType, setFunction, initValue, convertToThreshold, convertToSlider, signalOn) { - this.name = name; - this.type = type; - this.eventType = eventType; - this.signalType = signalType; - this.setValue = setFunction; - this.value = initValue; - this.get = function () { - return this.value; - }; - this.convertToThreshold = convertToThreshold; - this.convertToSlider = convertToSlider; -} - -// var HTML_URL = Script.resolvePath("file:///c:/dev/hifi_fork/hifi/scripts/developer/rotateRecenterApp.html"); -var HTML_URL = Script.resolvePath("http://hifi-content.s3.amazonaws.com/angus/stepApp/rotateRecenterApp.html"); -var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); - -// define the sliders -var filterLengthProperty = new AppProperty("#filterLength-slider", "slider", "onFilterLengthSlider", "filterSignal", - setFilterLength, DEFAULT_HEAD_TURN_FILTER_LENGTH, function (num) { - var base = 5; - var shift = 0; - return convertExponential(base, num, INCREASING, shift); - }, function (num) { - var base = 5; - var shift = 0; - return convertLog(base, num, INCREASING, shift); - }, true); -var angleThresholdProperty = new AppProperty("#angleThreshold-slider", "slider", "onAngleThresholdSlider", "angleSignal", - setAngleThreshold, DEFAULT_HEAD_TURN_THRESHOLD, function (num) { - return convertToRadians(num); - }, function (num) { - return convertToDegrees(num); - }, true); - -var propArray = new Array(filterLengthProperty, angleThresholdProperty); - -function setFilterLength(num) { - filterLengthProperty.value = num; - MyAvatar.rotationRecenterFilterLength = filterLengthProperty.value; - -} - -function setAngleThreshold(num) { - angleThresholdProperty.value = num; - MyAvatar.rotationThreshold = angleThresholdProperty.value; -} - -function convertToRadians(num) { - return (num / DEGREES_PER_PI_RADIANS) * Math.PI; -} - -function convertToDegrees(num) { - return (num / Math.PI) * DEGREES_PER_PI_RADIANS; -} - -function getLog(x, y) { - return Math.log(y) / Math.log(x); -} - -function convertLog(base, num, direction, shift) { - return direction * getLog(base, (num + FILTER_FUDGE_RANGE)) + shift; -} - -function convertExponential(base, num, direction, shift) { - return Math.pow(base, (direction * num + shift)) - FILTER_FUDGE_RANGE; -} - -function manageClick() { - if (activated) { - tablet.gotoHomeScreen(); - } else { - tablet.gotoWebScreen(HTML_URL); - } -} - -var tabletButton = tablet.addButton({ - text: TABLET_BUTTON_NAME, - icon: Script.resolvePath("http://hifi-content.s3.amazonaws.com/angus/stepApp/foot.svg"), - activeIcon: Script.resolvePath("http://hifi-content.s3.amazonaws.com/angus/stepApp/foot.svg") -}); - -function onKeyPress(event) { - if (event.text === "'") { - // when the sensors are reset, then reset the mode. - } -} - -function onWebEventReceived(msg) { - var message = JSON.parse(msg); - print(" we have a message from html dialog " + message.type); - propArray.forEach(function (prop) { - if (prop.eventType === message.type) { - prop.setValue(prop.convertToThreshold(message.data.value)); - print("message from " + prop.name); - // break; - } - }); - checkBoxArray.forEach(function(cbox) { - if (cbox.eventType === message.type) { - cbox.data.value = message.data.value; - if (cbox.id === "stepReset") { - MyAvatar.enableStepResetRotation = cbox.data.value; - } - if (cbox.id === "drawAverage") { - MyAvatar.enableDrawAverageFacing = cbox.data.value; - } - // break; - } - - }); - if (message.type === "onCreateRotateApp") { - print("document loaded"); - documentLoaded = true; - Script.setTimeout(initAppForm, LOADING_DELAY); - } -} - -function initAppForm() { - print("step app is loaded: " + documentLoaded); - if (documentLoaded === true) { - propArray.forEach(function (prop) { - print(prop.name); - tablet.emitScriptEvent(JSON.stringify({ - "type": "slider", - "id": prop.name, - "data": { "value": prop.convertToSlider(prop.value) } - })); - }); - checkBoxArray.forEach(function (cbox) { - tablet.emitScriptEvent(JSON.stringify({ - "type": "checkboxtick", - "id": cbox.id, - "data": { value: cbox.data.value } - })); - }); - } - -} - - -function onScreenChanged(type, url) { - print("Screen changed"); - if (type === "Web" && url === HTML_URL) { - if (!activated) { - // hook up to event bridge - tablet.webEventReceived.connect(onWebEventReceived); - print("after connect web event"); - MyAvatar.hmdLeanRecenterEnabled = true; - } - activated = true; - } else { - if (activated) { - // disconnect from event bridge - tablet.webEventReceived.disconnect(onWebEventReceived); - documentLoaded = false; - } - activated = false; - } -} - -function limitAngle(angle) { - return (angle + 180) % 360 - 180; -} - -function computeHandAzimuths(timeElapsed) { - - // var leftHandPositionRigSpace = Vec3.multiplyQbyV(Quat.inverse(CHANGE_OF_BASIS_ROTATION), currentStateReadings.lhandPose.translation); - // var rightHandPositionRigSpace = Vec3.multiplyQbyV(Quat.inverse(CHANGE_OF_BASIS_ROTATION), currentStateReadings.rhandPose.translation); - - - // var hipToLeftHand = Quat.lookAtSimple({ x: 0, y: 0, z: 0 }, { x: leftHandPositionRigSpace.x, y: 0, z: leftHandPositionRigSpace.z }); - // var hipToRightHand = Quat.lookAtSimple({ x: 0, y: 0, z: 0 }, { x: rightHandPositionRigSpace.x, y: 0, z: rightHandPositionRigSpace.z }); - // var hipToHandHalfway = Quat.slerp(hipToLeftHand, hipToRightHand, 0.5); - - var leftHand = currentStateReadings.lhandPose.translation; - var rightHand = currentStateReadings.rhandPose.translation; - var head = currentStateReadings.headPose.translation; - var lHandMinusHead = Vec3.subtract(leftHand, head); - lHandMinusHead.y = 0.0; - var rHandMinusHead = Vec3.subtract(rightHand, head); - rHandMinusHead.y = 0.0; - //print(JSON.stringify(leftHand)); - //print(JSON.stringify(head)); - var avatarZAxis = { x: 0.0, y: 0.0, z: 1.0 }; - var hipToLHand = Quat.lookAtSimple({ x: 0, y: 0, z: 0 }, lHandMinusHead); - var hipToRHand = Quat.lookAtSimple({ x: 0, y: 0, z: 0 }, rHandMinusHead); - var tau = timeElapsed / filterLengthProperty.value; - hipToLHandAverage = Quat.slerp(hipToLHandAverage, hipToLHand, tau); - hipToRHandAverage = Quat.slerp(hipToRHandAverage, hipToRHand, tau); - - // var angleToLeft = limitAngle(Quat.safeEulerAngles(hipToLHandAverage).y); - // var angleToRight = limitAngle(Quat.safeEulerAngles(hipToRHandAverage).y); - var leftRightMidpoint = (Quat.safeEulerAngles(hipToLHand).y + Quat.safeEulerAngles(hipToRHand).y) / 2.0; - var leftRightMidpointAverage = (Quat.safeEulerAngles(hipToLHandAverage).y + Quat.safeEulerAngles(hipToRHandAverage).y) / 2.0; - - // limit the angle because we are flipped by 180, fix this tomorrow. - // print(leftRightMidpointAverage/180.0); - // print("threshold value " + angleThresholdProperty.value); - - - var raySpineRotation = Quat.fromVec3Degrees({ x: 0, y: leftRightMidpointAverage, z: 0 }); - var zAxisSpineRotation = Vec3.multiplyQbyV(raySpineRotation, { x: 0, y: 0, z: -1 }); - var zAxisWorldSpace = Vec3.multiplyQbyV(MyAvatar.orientation, zAxisSpineRotation); - // DebugDraw.drawRay(MyAvatar.position, Vec3.sum(MyAvatar.position, zAxisWorldSpace), { x: 1, y: 0, z: 0, w: 1 }); - - //print(leftRightMidpoint); - - var headPoseRigSpace = Quat.multiply(CHANGE_OF_BASIS_ROTATION, currentStateReadings.head.rotation); - headPoseAverageOrientation = Quat.slerp(headPoseAverageOrientation, headPoseRigSpace, tau); - var headPoseAverageEulers = Quat.safeEulerAngles(headPoseAverageOrientation); - - // get it into radians too!! - // average head and hands 50/50 - // print("hands azimuth " + leftRightMidpointAverage + " head azimuth " + headPoseAverageEulers.y); - var headPlusHands = (leftRightMidpointAverage + headPoseAverageEulers.y) / 2.0; - if ((Math.abs(headPlusHands / 180.0) * Math.PI) > angleThresholdProperty.value) { - //print("recenter the feet under the head"); - // MyAvatar.triggerRotationRecenter(); - hipToLHandAverage = { x: 0, y: 0, z: 0, w: 1 }; - hipToRHandAverage = { x: 0, y: 0, z: 0, w: 1 }; - headPoseAverageOrientation = { x: 0, y: 0, z: 0, w: 1 }; - } - - // put a hard max on this easing function. - var rotateAngle = ((Math.cos((leftRightMidpoint / 180.0) * Math.PI) + 2.0)/3.0) * leftRightMidpoint; - //print("rotate angle " + rotateAngle); - - return Quat.fromVec3Degrees({ x: 0, y: rotateAngle, z: 0 }); - - -} - -function update(dt) { - //update state readings - currentStateReadings.head = Controller.getPoseValue(Controller.Standard.Head); - currentStateReadings.rhandPose = Controller.getPoseValue(Controller.Standard.RightHand); - currentStateReadings.lhandPose = Controller.getPoseValue(Controller.Standard.LeftHand); - - //print(JSON.stringify(currentStateReadings.head)); - - - - var latestSpineRotation = computeHandAzimuths(dt); - - spine2Rotation = latestSpineRotation; - var spine2Pos = MyAvatar.getAbsoluteJointTranslationInObjectFrame(MyAvatar.getJointIndex("Spine2")); - spine2PositionRigSpace = Vec3.multiplyQbyV(CHANGE_OF_BASIS_ROTATION, spine2Pos); - /* - if (HMD.active && !scriptLoaded) { - //Script.load("rotateApp.js"); - scriptLoaded = true; - } - - if (!HMD.active) { - scriptLoaded = false; - } - */ - - // handle the azimuth of the arms - -} - -function shutdownTabletApp() { - tablet.removeButton(tabletButton); - if (activated) { - tablet.webEventReceived.disconnect(onWebEventReceived); - tablet.gotoHomeScreen(); - } - tablet.screenChanged.disconnect(onScreenChanged); -} - -Script.setTimeout(function () { - tabletButton.clicked.connect(manageClick); - tablet.screenChanged.connect(onScreenChanged); - Script.update.connect(update); - Controller.keyPressEvent.connect(onKeyPress); -}, (LOADING_DELAY)); - -Script.scriptEnding.connect(function () { - // if (handlerId) { - // print("removing animation state handler"); - // handlerId = MyAvatar.removeAnimationStateHandler(handlerId); - // } - MyAvatar.hmdLeanRecenterEnabled = true; - Script.update.disconnect(update); - shutdownTabletApp(); -}); \ No newline at end of file From 7dfdc796448e23c5f231a3c319fe64c94fa1abdb Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 28 Aug 2018 12:21:15 -0700 Subject: [PATCH 135/545] Picking pid values --- interface/src/LODManager.cpp | 5 ++++- interface/src/LODManager.h | 2 +- scripts/developer/utilities/render/lod.qml | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index 91a547cf31..411e0156b5 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -103,7 +103,10 @@ void LODManager::autoAdjustLOD(float realTimeDelta) { auto output = Kp * error + Ki * integral + Kd * derivative; previous_error = error; - auto newSolidAngle = std::max( 0.1f, std::min(output, 45.f)); + + auto newSolidAngle = oldSolidAngle + output; + + newSolidAngle = std::max( 0.5f, std::min(newSolidAngle, 90.f)); auto halTan = glm::tan(glm::radians(newSolidAngle * 0.5f)); diff --git a/interface/src/LODManager.h b/interface/src/LODManager.h index 2251281ae2..b2e324a820 100644 --- a/interface/src/LODManager.h +++ b/interface/src/LODManager.h @@ -237,7 +237,7 @@ private: float _octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE; int _boundaryLevelAdjust = 0; - glm::vec4 _pid{ 0.1f, 0.0f, 0.0f, 3.0f }; + glm::vec4 _pid{ 0.06f, 0.005f, 0.01f, 4.0f }; uint64_t _decreaseFPSExpiry { 0 }; uint64_t _increaseFPSExpiry { 0 }; diff --git a/scripts/developer/utilities/render/lod.qml b/scripts/developer/utilities/render/lod.qml index 742e8c0dc1..1ca9b68de2 100644 --- a/scripts/developer/utilities/render/lod.qml +++ b/scripts/developer/utilities/render/lod.qml @@ -98,7 +98,7 @@ Item { label: "LOD PID Ki" valueVar: LODManager["pidKi"] valueVarSetter: (function (v) { LODManager["pidKi"] = v }) - max: 1.0 + max: 0.02 min: 0.0 integral: false @@ -111,7 +111,7 @@ Item { label: "LOD PID Kd" valueVar: LODManager["pidKd"] valueVarSetter: (function (v) { LODManager["pidKd"] = v }) - max: 1.0 + max: 0.1 min: 0.0 integral: false From 8a9ad421e7fd69338e74236dea9a629519f35ad1 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Tue, 28 Aug 2018 15:50:14 -0700 Subject: [PATCH 136/545] adding serverless file + redirection if conn fail --- interface/CMakeLists.txt | 5 +++ interface/resources/serverless/redirect.json | 1 + interface/src/Application.cpp | 33 ++++++++++++++++++++ interface/src/Application.h | 1 + libraries/networking/src/AddressManager.cpp | 2 +- libraries/networking/src/AddressManager.h | 1 + 6 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 interface/resources/serverless/redirect.json diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 990d84a774..cd058add94 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -341,6 +341,8 @@ else() set(INTERFACE_EXEC_DIR "$") set(RESOURCES_DEV_DIR "${INTERFACE_EXEC_DIR}/resources") + message(STATUS "${RESOURCES_DEV_DIR}") + # copy the resources files beside the executable add_custom_command(TARGET ${TARGET_NAME} POST_BUILD COMMAND "${CMAKE_COMMAND}" -E copy_if_different @@ -360,6 +362,9 @@ else() COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${PROJECT_SOURCE_DIR}/resources/serverless/tutorial.json" "${RESOURCES_DEV_DIR}/serverless/tutorial.json" + COMMAND "${CMAKE_COMMAND}" -E copy_if_different + "${PROJECT_SOURCE_DIR}/resources/serverless/redirect.json" + "${RESOURCES_DEV_DIR}/serverless/redirect.json" # copy JSDoc files beside the executable COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_SOURCE_DIR}/tools/jsdoc/out" diff --git a/interface/resources/serverless/redirect.json b/interface/resources/serverless/redirect.json new file mode 100644 index 0000000000..d97f44220a --- /dev/null +++ b/interface/resources/serverless/redirect.json @@ -0,0 +1 @@ +{"DataVersion": 0, "Entities": [{"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{9a50eca4-5c97-4e21-8cb9-5197bb09770e}", "lastEdited": 1535474935077402, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"albedoMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.9275937080383301, "x": -3.07240629196167, "y": -9.5, "z": 1.94891357421875}, "priority": 1, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.4799537658691406}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{2d90745c-2fe2-4f9c-9dcf-b715f7a9d0c0}", "lastEdited": 1535474935076550, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"albedoMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.9275937080383301, "x": -3.07240629196167, "y": -9.5, "z": 1.94891357421875}, "priority": 1, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.4799537658691406}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{dcbca0fd-e1d8-4248-b2b4-b91346224876}", "lastEdited": 1535474935077745, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"emissiveMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel_highlight.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.927593469619751, "x": -3.072406530380249, "y": -9.5, "z": 1.94891357421875}, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.479954719543457}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{3df15ffb-9614-4ec1-81a8-e278d1917748}", "lastEdited": 1535474935076889, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"emissiveMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel_highlight.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.9275937080383301, "x": -3.07240629196167, "y": -9.5, "z": 1.94891357421875}, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.4799537658691406}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{fd138f98-d436-41d2-863a-cbef6e41e1cb}", "lastEdited": 1535474935078215, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"albedoMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.9275937080383301, "x": -3.07240629196167, "y": -9.5, "z": 1.94891357421875}, "priority": 1, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.4799537658691406}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{b2a90f9e-a5ec-4faa-a6a3-bc457516f5ee}", "lastEdited": 1535474935077505, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"albedoMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.9275937080383301, "x": -3.07240629196167, "y": -9.5, "z": 1.94891357421875}, "priority": 1, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.4799537658691406}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{5c9ef440-f022-4d21-9f00-22827851b522}", "lastEdited": 1535474935077201, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"emissiveMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel_highlight.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.948914527893066, "green": 0.16741032898426056, "red": 0.9275782108306885, "x": -3.0724217891693115, "y": -9.33258967101574, "z": 1.9489145278930664}, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904473781585693, "y": 1.028862476348877, "z": -2.479969024658203}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{2fe2296a-d74d-4ee7-bf7d-c9665bc63237}", "lastEdited": 1535474935076656, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"emissiveMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel_highlight.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.9275937080383301, "x": -3.07240629196167, "y": -9.5, "z": 1.94891357421875}, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.4799537658691406}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{86f1ba10-2921-45ad-bb74-dcbe5c49bc69}", "lastEdited": 1535474935077298, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"emissiveMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel_highlight.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.9275937080383301, "x": -3.07240629196167, "y": -9.5, "z": 1.94891357421875}, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.4799537658691406}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{1023380c-13dd-445d-bb57-1e02574e5cb3}", "lastEdited": 1535474935076124, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"emissiveMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel_highlight.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.9275937080383301, "x": -3.07240629196167, "y": -9.5, "z": 1.94891357421875}, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.4799537658691406}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{d5d841b2-0cc0-4ab2-84fe-dce3d20f6b04}", "lastEdited": 1535474935077609, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"emissiveMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel_highlight.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.927593469619751, "x": -3.072406530380249, "y": -9.5, "z": 1.94891357421875}, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.479954719543457}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{02da6c73-bab0-4e7e-b8fc-a9c0500ac66e}", "lastEdited": 1535474935075994, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"albedoMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.9275937080383301, "x": -3.07240629196167, "y": -9.5, "z": 1.94891357421875}, "priority": 1, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.4799537658691406}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{f1c2110e-1429-49b2-949d-6c73718b2d65}", "lastEdited": 1535474935078059, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"albedoMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.9275937080383301, "x": -3.07240629196167, "y": -9.5, "z": 1.94891357421875}, "priority": 1, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.4799537658691406}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{1e09084f-c0d7-4bd4-a78d-290c03391579}", "lastEdited": 1535474935076234, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"emissiveMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel_highlight.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.927593469619751, "x": -3.072406530380249, "y": -9.5, "z": 1.94891357421875}, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.479954719543457}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{e8282a17-76a5-4cd8-9f0e-473f097c8ad1}", "lastEdited": 1535474935077902, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"albedoMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.9275937080383301, "x": -3.07240629196167, "y": -9.5, "z": 1.94891357421875}, "priority": 1, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.4799537658691406}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{46fbad8a-5bc0-44c8-a9ca-beb38f672d2a}", "lastEdited": 1535474935076994, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"albedoMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.9275937080383301, "x": -3.07240629196167, "y": -9.5, "z": 1.94891357421875}, "priority": 1, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.4799537658691406}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{2861b544-1c03-439a-85ad-3758ba87ca55}", "lastEdited": 1535474935076339, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"emissiveMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel_highlight.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.9275937080383301, "x": -3.07240629196167, "y": -9.5, "z": 1.94891357421875}, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.4799537658691406}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{59b7fc7f-0100-4115-a9f8-55d5b45da540}", "lastEdited": 1535474935077098, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"albedoMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.9275937080383301, "x": -3.07240629196167, "y": -9.5, "z": 1.94891357421875}, "priority": 1, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.4799537658691406}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{2888e4b0-6eb1-4468-9b95-893dcb3e99a5}", "lastEdited": 1535474935076443, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"emissiveMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel_highlight.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.9275937080383301, "x": -3.07240629196167, "y": -9.5, "z": 1.94891357421875}, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.4799537658691406}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{36f00cad-64b0-415f-9f70-e92cd85836d8}", "lastEdited": 1535474935076783, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"albedoMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.9275937080383301, "x": -3.07240629196167, "y": -9.5, "z": 1.94891357421875}, "priority": 1, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.4799537658691406}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": false, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 14.40000057220459, "green": 14.40000057220459, "red": 14.40000057220459, "x": 14.40000057220459, "y": 14.40000057220459, "z": 14.40000057220459}, "id": "{2cefd6b6-6a00-49c3-87c8-71b9c83f96f1}", "lastEdited": 1535474935056115, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": {"blue": 2.3440732955932617, "green": 1.7684326171875, "red": 1.8812973499298096, "x": -2.1187026500701904, "y": -7.7315673828125, "z": -1.6559267044067383}, "queryAACube": {"scale": 24.9415340423584, "x": -10.589469909667969, "y": -10.7023344039917, "z": -10.126693725585938}, "rotation": {"w": 0.8697794675827026, "x": -1.52587890625e-05, "y": 0.4933699369430542, "z": -4.57763671875e-05}, "shapeType": "box", "skyboxMode": "enabled", "type": "Zone", "userData": "{\"grabbableKey\":{\"grabbable\":false}}"}, {"clientOnly": false, "color": {"blue": 0, "green": 0, "red": 0}, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 11.117486953735352, "green": 3.580313205718994, "red": 0.20000000298023224, "x": 0.20000000298023224, "y": 3.580313205718994, "z": 11.117486953735352}, "id": "{efde7819-3a7a-4984-ac3e-28bcf69c6b1e}", "lastEdited": 1535474935053285, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": {"blue": 0, "green": 1.1583251953125, "red": 4.971565246582031, "x": 0.9715652465820312, "y": -8.3416748046875, "z": -4}, "queryAACube": {"scale": 11.681488037109375, "x": -0.8691787719726562, "y": -4.6824188232421875, "z": -5.8407440185546875}, "rotation": {"w": 0.8637980222702026, "x": -4.57763671875e-05, "y": 0.5038070678710938, "z": -1.52587890625e-05}, "shape": "Cube", "type": "Box", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": false, "color": {"blue": 0, "green": 0, "red": 0}, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 11.117486953735352, "green": 3.580313205718994, "red": 0.20000000298023224, "x": 0.20000000298023224, "y": 3.580313205718994, "z": 11.117486953735352}, "id": "{fe8d6b12-3697-4fcd-9092-af5b7f49a7f5}", "lastEdited": 1535474947253763, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": {"blue": 5.268576622009277, "green": 1.1588134765625, "red": 6.100250244140625, "x": 2.100250244140625, "y": -8.3411865234375, "z": 1.2685766220092773}, "queryAACube": {"scale": 11.681488037109375, "x": 0.2595062255859375, "y": -4.6819305419921875, "z": -0.5721673965454102}, "rotation": {"w": 0.9662165641784668, "x": -4.57763671875e-05, "y": -0.2576791048049927, "z": 1.52587890625e-05}, "shape": "Cube", "type": "Box", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": false, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 0.06014331430196762, "green": 2.582186460494995, "red": 2.582186698913574, "x": 2.582186698913574, "y": 2.582186460494995, "z": 0.06014331430196762}, "id": "{c8f9b1b1-3bd7-473c-8c2a-a8644a7acdd7}", "lastEdited": 1535474935054058, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "modelURL": "http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/oopsDialog.fbx", "name": "Oops Dialog", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": {"blue": 1.45927095413208, "green": 1.6763916015625, "red": 0, "x": -4, "y": -7.8236083984375, "z": -2.54072904586792}, "queryAACube": {"scale": 3.6522583961486816, "x": -1.8261291980743408, "y": -0.14973759651184082, "z": -0.36685824394226074}, "rotation": {"w": 0.8684672117233276, "x": -4.57763671875e-05, "y": 0.4957197904586792, "z": -7.62939453125e-05}, "type": "Model", "userData": "{\"grabbableKey\":{\"grabbable\":false}}"}, {"angularDamping": 0, "clientOnly": false, "color": {"blue": 0, "green": 0, "red": 255}, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 0.20000000298023224, "green": 0.20000000298023224, "red": 0.20000000298023224, "x": 0.20000000298023224, "y": 0.20000000298023224, "z": 0.20000000298023224}, "id": "{d0b0491a-5c7d-4cd2-9ebe-492b709a702b}", "lastEdited": 1535474935052912, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "name": "Particle Rotate", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": {"blue": 3.8216662406921387, "green": 0, "red": 1.2409718036651611, "x": -2.759028196334839, "y": -9.5, "z": -0.17833375930786133}, "queryAACube": {"scale": 0.3464101552963257, "x": 1.0677666664123535, "y": -0.17320507764816284, "z": 3.648461103439331}, "rotation": {"w": 0.6444342136383057, "x": -0.08220034837722778, "y": -0.6649118661880493, "z": 0.3684900999069214}, "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", "scriptTimestamp": 1532724769253, "shape": "Cube", "type": "Box", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"angularDamping": 0, "clientOnly": false, "color": {"blue": 0, "green": 0, "red": 255}, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 0.20000000298023224, "green": 0.20000000298023224, "red": 0.20000000298023224, "x": 0.20000000298023224, "y": 0.20000000298023224, "z": 0.20000000298023224}, "id": "{ae4a84ee-4e95-4e6b-b63d-399893a9b3f9}", "lastEdited": 1535474935052114, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "name": "Particle Rotate", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": {"blue": 1.3116319179534912, "green": 0, "red": 2.705613613128662, "x": -1.294386386871338, "y": -9.5, "z": -2.688368082046509}, "queryAACube": {"scale": 0.3464101552963257, "x": 2.5324084758758545, "y": -0.17320507764816284, "z": 1.1384267807006836}, "rotation": {"w": 0.9127794504165649, "x": 0.2575265169143677, "y": 0.15553522109985352, "z": 0.2761729955673218}, "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", "scriptTimestamp": 1532724769253, "shape": "Cube", "type": "Box", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"angularDamping": 0, "clientOnly": false, "color": {"blue": 0, "green": 0, "red": 255}, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 0.20000000298023224, "green": 0.20000000298023224, "red": 0.20000000298023224, "x": 0.20000000298023224, "y": 0.20000000298023224, "z": 0.20000000298023224}, "id": "{c1404297-9c6a-4d2d-b91d-c844ddd391db}", "lastEdited": 1535474935051740, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "name": "Particle Rotate", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": {"blue": 3.8216662406921387, "green": 0.0772705078125, "red": 1.2409718036651611, "x": -2.759028196334839, "y": -9.4227294921875, "z": -0.17833375930786133}, "queryAACube": {"scale": 0.3464101552963257, "x": 1.0677666664123535, "y": -0.09593456983566284, "z": 3.648461103439331}, "rotation": {"w": 0.926024317741394, "x": 0.20308232307434082, "y": -0.010269343852996826, "z": 0.3179827928543091}, "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", "scriptTimestamp": 1532724769253, "shape": "Cube", "type": "Box", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": false, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 9.030570983886719, "green": 0.0719478651881218, "red": 9.030570983886719, "x": 9.030570983886719, "y": 0.0719478651881218, "z": 9.030570983886719}, "id": "{f17920f3-1571-4c5e-b002-e328cf202037}", "lastEdited": 1535474950564649, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "modelURL": "http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/floor.fbx", "name": "Floor", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": {"blue": 4.2324604988098145, "green": 0.17547607421875, "red": 4.802988529205322, "x": 0.8029885292053223, "y": -9.32452392578125, "z": 0.23246049880981445}, "queryAACube": {"scale": 12.771358489990234, "x": -1.582690715789795, "y": -6.210203170776367, "z": -2.1532187461853027}, "rotation": {"w": 0.8648051023483276, "x": -1.52587890625e-05, "y": 0.5020675659179688, "z": -4.57763671875e-05}, "shapeType": "simple-hull", "type": "Model", "userData": "{\"grabbableKey\":{\"grabbable\":false}}"}, {"alpha": 0, "alphaFinish": 0, "alphaStart": 0.25, "clientOnly": false, "colorFinish": {"blue": 0, "green": 0, "red": 0, "x": 0, "y": 0, "z": 0}, "colorStart": {"blue": 255, "green": 255, "red": 255, "x": 255, "y": 255, "z": 255}, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 13.24000072479248, "green": 13.24000072479248, "red": 13.24000072479248, "x": 13.24000072479248, "y": 13.24000072479248, "z": 13.24000072479248}, "emitAcceleration": {"blue": 0, "green": 0.10000000149011612, "red": 0, "x": 0, "y": 0.10000000149011612, "z": 0}, "emitDimensions": {"blue": 1, "green": 1, "red": 1, "x": 1, "y": 1, "z": 1}, "emitOrientation": {"w": 1, "x": -1.52587890625e-05, "y": -1.52587890625e-05, "z": -1.52587890625e-05}, "emitRate": 6, "emitSpeed": 0, "id": "{7561445a-4f9c-41aa-96b9-b8ce8ad686d3}", "lastEdited": 1535474935056499, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "lifespan": 10, "maxParticles": 10, "name": "Stars", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "particleRadius": 0.07000000029802322, "polarFinish": 3.1415927410125732, "position": {"blue": 1.3712034225463867, "green": 0.5220947265625, "red": 2.6281180381774902, "x": -1.3718819618225098, "y": -8.9779052734375, "z": -2.6287965774536133}, "queryAACube": {"scale": 22.932353973388672, "x": -8.838058471679688, "y": -10.944082260131836, "z": -10.09497356414795}, "radiusFinish": 0, "radiusStart": 0, "rotation": {"w": 0.9852597713470459, "x": -1.52587890625e-05, "y": -0.17106890678405762, "z": -7.62939453125e-05}, "speedSpread": 0, "spinFinish": null, "spinStart": null, "textures": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/star.png", "type": "ParticleEffect", "userData": "{\"grabbableKey\":{\"grabbable\":false}}"}, {"alpha": 0, "alphaFinish": 0, "alphaStart": 1, "clientOnly": false, "color": {"blue": 255, "green": 205, "red": 3}, "colorFinish": {"blue": 0, "green": 0, "red": 0, "x": 0, "y": 0, "z": 0}, "colorStart": {"blue": 255, "green": 204, "red": 0, "x": 0, "y": 204, "z": 255}, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 2.5, "green": 2.5, "red": 2.5, "x": 2.5, "y": 2.5, "z": 2.5}, "emitAcceleration": {"blue": 0, "green": 0, "red": 0, "x": 0, "y": 0, "z": 0}, "emitDimensions": {"blue": 1, "green": 1, "red": 1, "x": 1, "y": 1, "z": 1}, "emitOrientation": {"w": 0.9993909597396851, "x": 0.034897372126579285, "y": -1.525880907138344e-05, "z": -1.525880907138344e-05}, "emitRate": 2, "emitSpeed": 0, "emitterShouldTrail": true, "id": "{7c59b77f-2f88-4c35-899b-3e42bd486ed6}", "lastEdited": 1535474935050547, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "lifespan": 10, "maxParticles": 40, "name": "Rays", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "particleRadius": 0.75, "polarFinish": 3.1415927410125732, "position": {"blue": 3.814434051513672, "green": 1.44122314453125, "red": 1.2319090366363525, "x": -2.7680909633636475, "y": -8.05877685546875, "z": -0.18556594848632812}, "queryAACube": {"scale": 4.330127239227295, "x": -0.9331545829772949, "y": -0.7238404750823975, "z": 1.6493704319000244}, "radiusFinish": 0.10000000149011612, "radiusStart": 0, "rotation": {"w": 0.9594720602035522, "x": -1.52587890625e-05, "y": 0.28178834915161133, "z": -4.57763671875e-05}, "speedSpread": 0, "spinFinish": null, "spinStart": null, "textures": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/stripe.png", "type": "ParticleEffect", "userData": "{\"grabbableKey\":{\"grabbable\":false}}"}, {"angularDamping": 0, "clientOnly": false, "color": {"blue": 0, "green": 0, "red": 255}, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 0.20000000298023224, "green": 0.20000000298023224, "red": 0.20000000298023224, "x": 0.20000000298023224, "y": 0.20000000298023224, "z": 0.20000000298023224}, "id": "{55dd2b28-1c53-431b-b2ea-61155dfc6652}", "lastEdited": 1535474935055239, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "name": "Particle Rotate", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": {"blue": 1.3116319179534912, "green": 0.15618896484375, "red": 2.705613613128662, "x": -1.294386386871338, "y": -9.34381103515625, "z": -2.688368082046509}, "queryAACube": {"scale": 0.3464101552963257, "x": 2.5324084758758545, "y": -0.017016112804412842, "z": 1.1384267807006836}, "rotation": {"w": 0.46953535079956055, "x": -0.16719311475753784, "y": -0.7982757091522217, "z": 0.3380941152572632}, "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", "scriptTimestamp": 1532724769253, "shape": "Cube", "type": "Box", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"angularDamping": 0, "clientOnly": false, "color": {"blue": 0, "green": 0, "red": 255}, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 0.20000000298023224, "green": 0.20000000298023224, "red": 0.20000000298023224, "x": 0.20000000298023224, "y": 0.20000000298023224, "z": 0.20000000298023224}, "id": "{f40563f7-01e3-4faf-ad1b-19cab7a386a1}", "lastEdited": 1535474935054426, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "name": "Particle Rotate", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": {"blue": 1.3116319179534912, "green": 0.0772705078125, "red": 2.705613613128662, "x": -1.294386386871338, "y": -9.4227294921875, "z": -2.688368082046509}, "queryAACube": {"scale": 0.3464101552963257, "x": 2.5324084758758545, "y": -0.09593456983566284, "z": 1.1384267807006836}, "rotation": {"w": -0.38777750730514526, "x": -0.37337303161621094, "y": -0.8409399390220642, "z": 0.055222392082214355}, "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", "scriptTimestamp": 1532724769253, "shape": "Cube", "type": "Box", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"alpha": 0, "alphaFinish": 0, "alphaStart": 1, "clientOnly": false, "color": {"blue": 211, "green": 227, "red": 104}, "colorFinish": {"blue": 0, "green": 0, "red": 0, "x": 0, "y": 0, "z": 0}, "colorStart": {"blue": 211, "green": 227, "red": 104, "x": 104, "y": 227, "z": 211}, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 2.5, "green": 2.5, "red": 2.5, "x": 2.5, "y": 2.5, "z": 2.5}, "emitAcceleration": {"blue": 0, "green": 0, "red": 0, "x": 0, "y": 0, "z": 0}, "emitDimensions": {"blue": 1, "green": 1, "red": 1, "x": 1, "y": 1, "z": 1}, "emitOrientation": {"w": 0.9993909597396851, "x": 0.034897372126579285, "y": -1.525880907138344e-05, "z": -1.525880907138344e-05}, "emitRate": 2, "emitSpeed": 0, "id": "{c4a86707-2eaa-41f5-a1ad-3e6029178d75}", "lastEdited": 1535474935052538, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "lifespan": 10, "maxParticles": 40, "name": "Rays", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "particleRadius": 0.75, "polarFinish": 3.1415927410125732, "position": {"blue": 1.3553659915924072, "green": 1.44122314453125, "red": 2.572803497314453, "x": -1.4271965026855469, "y": -8.05877685546875, "z": -2.6446340084075928}, "queryAACube": {"scale": 4.330127239227295, "x": 0.40773987770080566, "y": -0.7238404750823975, "z": -0.8096976280212402}, "radiusFinish": 0.10000000149011612, "radiusStart": 0, "rotation": {"w": 0.9803768396377563, "x": -1.52587890625e-05, "y": 0.19707024097442627, "z": -7.62939453125e-05}, "speedSpread": 0, "spinFinish": null, "spinStart": null, "textures": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/stripe.png", "type": "ParticleEffect", "userData": "{\"grabbableKey\":{\"grabbable\":false}}"}, {"angularDamping": 0, "clientOnly": false, "color": {"blue": 0, "green": 0, "red": 255}, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 0.20000000298023224, "green": 0.20000000298023224, "red": 0.20000000298023224, "x": 0.20000000298023224, "y": 0.20000000298023224, "z": 0.20000000298023224}, "id": "{65dd9c7f-815d-4b50-ba3b-24709691aed1}", "lastEdited": 1535474935056805, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "name": "Particle Rotate", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": {"blue": 3.8216662406921387, "green": 0.15618896484375, "red": 1.2409718036651611, "x": -2.759028196334839, "y": -9.34381103515625, "z": -0.17833375930786133}, "queryAACube": {"scale": 0.3464101552963257, "x": 1.0677666664123535, "y": -0.017016112804412842, "z": 3.648461103439331}, "rotation": {"w": 0.6747081279754639, "x": -0.06532388925552368, "y": -0.6342412233352661, "z": 0.37175559997558594}, "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", "scriptTimestamp": 1532724769253, "shape": "Cube", "type": "Box", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": false, "color": {"blue": 0, "green": 0, "red": 0}, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 11.117486953735352, "green": 3.580313205718994, "red": 0.20000000298023224, "x": 0.20000000298023224, "y": 3.580313205718994, "z": 11.117486953735352}, "id": "{4e0f3381-ac88-48ab-9378-0b7818188234}", "lastEdited": 1535474935053657, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": {"blue": 6.1806135177612305, "green": 1.1588134765625, "red": 1.4755167961120605, "x": -2.5244832038879395, "y": -8.3411865234375, "z": 2.1806135177612305}, "queryAACube": {"scale": 11.681488037109375, "x": -4.365227222442627, "y": -4.6819305419921875, "z": 0.33986949920654297}, "rotation": {"w": 0.8637980222702026, "x": -4.57763671875e-05, "y": 0.5038070678710938, "z": -1.52587890625e-05}, "shape": "Cube", "type": "Box", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": false, "color": {"blue": 0, "green": 0, "red": 0}, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 11.117486953735352, "green": 3.580313205718994, "red": 0.20000000298023224, "x": 0.20000000298023224, "y": 3.580313205718994, "z": 11.117486953735352}, "id": "{2da3a1d6-c757-4cc3-b20c-d7ec87eedd52}", "lastEdited": 1535474935050931, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": {"blue": 1.9063844680786133, "green": 1.15850830078125, "red": 0.16632509231567383, "x": -3.833674907684326, "y": -8.34149169921875, "z": -2.0936155319213867}, "queryAACube": {"scale": 11.681488037109375, "x": -5.674418926239014, "y": -4.6822357177734375, "z": -3.934359550476074}, "rotation": {"w": 0.9666743278503418, "x": -4.57763671875e-05, "y": -0.2560006380081177, "z": 1.52587890625e-05}, "shape": "Cube", "type": "Box", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"alpha": 0, "alphaFinish": 0, "alphaStart": 0.25, "clientOnly": false, "colorFinish": {"blue": 0, "green": 0, "red": 0, "x": 0, "y": 0, "z": 0}, "colorStart": {"blue": 255, "green": 255, "red": 255, "x": 255, "y": 255, "z": 255}, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 13.24000072479248, "green": 13.24000072479248, "red": 13.24000072479248, "x": 13.24000072479248, "y": 13.24000072479248, "z": 13.24000072479248}, "emitAcceleration": {"blue": 0, "green": 0.10000000149011612, "red": 0, "x": 0, "y": 0.10000000149011612, "z": 0}, "emitDimensions": {"blue": 1, "green": 1, "red": 1, "x": 1, "y": 1, "z": 1}, "emitOrientation": {"w": 1, "x": -1.52587890625e-05, "y": -1.52587890625e-05, "z": -1.52587890625e-05}, "emitRate": 6, "emitSpeed": 0, "emitterShouldTrail": true, "id": "{7db57102-9a57-48d6-9937-bcec7892c3d9}", "lastEdited": 1535474935058139, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "lifespan": 10, "maxParticles": 10, "name": "Stars", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "particleRadius": 0.07000000029802322, "polarFinish": 3.1415927410125732, "position": {"blue": 3.78922963142395, "green": 0.5220947265625, "red": 1.1928560733795166, "x": -2.8071439266204834, "y": -8.9779052734375, "z": -0.2107703685760498}, "queryAACube": {"scale": 22.932353973388672, "x": -10.273321151733398, "y": -10.944082260131836, "z": -7.676947593688965}, "radiusFinish": 0, "radiusStart": 0, "rotation": {"w": 0.996429443359375, "x": -1.52587890625e-05, "y": -0.08442819118499756, "z": -4.57763671875e-05}, "speedSpread": 0, "spinFinish": null, "spinStart": null, "textures": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/star.png", "type": "ParticleEffect", "userData": "{\"grabbableKey\":{\"grabbable\":false}}"}, {"clientOnly": false, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 2.1097896099090576, "green": 0.04847164824604988, "red": 1.458284616470337, "x": 1.458284616470337, "y": 0.04847164824604988, "z": 2.1097896099090576}, "id": "{434940be-0b45-4ca2-97db-91e698c20bfd}", "lastEdited": 1535474935055655, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "modelURL": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/portal2.fbx", "name": "Back", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": {"blue": 1.5835940837860107, "green": 0.2467041015625, "red": 3.0345542430877686, "x": -0.9654457569122314, "y": -9.2532958984375, "z": -2.4164059162139893}, "queryAACube": {"scale": 2.5651814937591553, "x": 1.751963496208191, "y": -1.0358866453170776, "z": 0.3010033369064331}, "rotation": {"w": 0.9084458351135254, "x": -1.52587890625e-05, "y": 0.4179598093032837, "z": -0.0001068115234375}, "type": "Model", "userData": "{\"grabbableKey\":{\"grabbable\":true}}"}, {"clientOnly": false, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 2.1097896099090576, "green": 0.04847164824604988, "red": 1.458284616470337, "x": 1.458284616470337, "y": 0.04847164824604988, "z": 2.1097896099090576}, "id": "{5f853b12-33b9-4f40-92a8-4506047fdcd8}", "lastEdited": 1535474935051356, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "modelURL": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/portal1.fbx", "name": "Try Again", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": {"blue": 3.946338653564453, "green": 0.2467041015625, "red": 1.6013128757476807, "x": -2.3986871242523193, "y": -9.2532958984375, "z": -0.053661346435546875}, "queryAACube": {"scale": 2.5651814937591553, "x": 0.318722128868103, "y": -1.0358866453170776, "z": 2.663747787475586}, "rotation": {"w": 0.8220492601394653, "x": -1.52587890625e-05, "y": 0.5693598985671997, "z": -0.0001068115234375}, "type": "Model", "userData": "{\"grabbableKey\":{\"grabbable\":true}}"}], "Id": "{aa6032b9-9c35-4481-acd9-03b97400b83a}", "Version": 93} \ No newline at end of file diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e290531471..7a8dd6c767 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1193,7 +1193,11 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo getOverlays().deleteOverlay(getTabletHomeButtonID()); getOverlays().deleteOverlay(getTabletFrameID()); }); +#if defined(Q_OS_ANDROID) connect(&domainHandler, &DomainHandler::domainConnectionRefused, this, &Application::domainConnectionRefused); +#else + connect(&domainHandler, &DomainHandler::domainConnectionRefused, this, &Application::domainConnectionRedirect); +#endif // We could clear ATP assets only when changing domains, but it's possible that the domain you are connected // to has gone down and switched to a new content set, so when you reconnect the cached ATP assets will no longer be valid. @@ -2313,6 +2317,35 @@ void Application::domainConnectionRefused(const QString& reasonMessage, int reas } } +void Application::domainConnectionRedirect(const QString& reasonMessage, int reasonCodeInt, const QString& extraInfo) { + DomainHandler::ConnectionRefusedReason reasonCode = static_cast(reasonCodeInt); + auto addressManager = DependencyManager::get(); + + if (reasonCode == DomainHandler::ConnectionRefusedReason::TooManyUsers && !extraInfo.isEmpty()) { + addressManager->handleLookupString(extraInfo); + return; + } + + switch (reasonCode) { + case DomainHandler::ConnectionRefusedReason::ProtocolMismatch: + case DomainHandler::ConnectionRefusedReason::TooManyUsers: + case DomainHandler::ConnectionRefusedReason::Unknown: { + QString message = "Unable to connect to the location you are visiting.\n"; + message += reasonMessage; + //OffscreenUi::asyncWarning("", message); + addressManager->handleLookupString(REDIRECT_HIFI_ADDRESS); + getMyAvatar()->setWorldVelocity(glm::vec3(0.0f)); + // in (w, x, y, z) component-structure for the constructor + getMyAvatar()->setWorldOrientation(glm::quat(0.8775935173034668f, 0.0f, 0.4794054925441742f, 0.0f)); + break; + } + default: + // nothing to do. + break; + } +} + + QString Application::getUserAgent() { if (QThread::currentThread() != thread()) { QString userAgent; diff --git a/interface/src/Application.h b/interface/src/Application.h index ae7e686f35..5255bb7d63 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -471,6 +471,7 @@ private slots: void updateDisplayMode(); void setDisplayPlugin(DisplayPluginPointer newPlugin); void domainConnectionRefused(const QString& reasonMessage, int reason, const QString& extraInfo); + void domainConnectionRedirect(const QString& reasonMessage, int reason, const QString& extraInfo); void addAssetToWorldCheckModelSize(); diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 00e552af89..0b69fda3fa 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -31,6 +31,7 @@ #include "udt/PacketHeaders.h" const QString DEFAULT_HIFI_ADDRESS = "file:///~/serverless/tutorial.json"; +const QString REDIRECT_HIFI_ADDRESS = "file:///~/serverless/redirect.json"; const QString ADDRESS_MANAGER_SETTINGS_GROUP = "AddressManager"; const QString SETTINGS_CURRENT_ADDRESS_KEY = "address"; @@ -709,7 +710,6 @@ bool AddressManager::handleViewpoint(const QString& viewpointString, bool should // We use _newHostLookupPath to determine if the client has already stored its last address // before moving to a new host thanks to the information in the same lookup URL. - if (definitelyPathOnly || (!pathString.isEmpty() && pathString != _newHostLookupPath) || trigger == Back || trigger == Forward) { addCurrentAddressToHistory(trigger); diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h index 37b85a9acd..245517d8cd 100644 --- a/libraries/networking/src/AddressManager.h +++ b/libraries/networking/src/AddressManager.h @@ -23,6 +23,7 @@ #include "AccountManager.h" extern const QString DEFAULT_HIFI_ADDRESS; +extern const QString REDIRECT_HIFI_ADDRESS; const QString SANDBOX_HIFI_ADDRESS = "hifi://localhost"; const QString INDEX_PATH = "/"; From 0da22db837d58c419ca0d58497c96164706b293c Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 28 Aug 2018 16:05:57 -0700 Subject: [PATCH 137/545] Picking pid values --- interface/src/Application.cpp | 2 +- interface/src/LODManager.cpp | 86 +++++++++++++------ interface/src/LODManager.h | 23 +++-- .../render/configSlider/RichSlider.qml | 3 +- scripts/developer/utilities/render/lod.qml | 52 ++++++----- 5 files changed, 112 insertions(+), 54 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 817c6b1e43..e7b17b3d69 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5987,7 +5987,7 @@ void Application::updateRenderArgs(float deltaTime) { _viewFrustum.calculate(); } appRenderArgs._renderArgs = RenderArgs(_gpuContext, lodManager->getOctreeSizeScale(), - lodManager->getBoundaryLevelAdjust(), lodManager->getSolidAngleHalfTan(), RenderArgs::DEFAULT_RENDER_MODE, + lodManager->getBoundaryLevelAdjust(), lodManager->getLODAngleHalfTan(), RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); appRenderArgs._renderArgs._scene = getMain3DScene(); diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index 411e0156b5..7f99e74a2a 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -75,12 +75,8 @@ void LODManager::autoAdjustLOD(float realTimeDelta) { return; } - auto Kp = _pid.x; - auto Ki = _pid.y; - auto Kd = _pid.z; - float oldOctreeSizeScale = _octreeSizeScale; - float oldSolidAngle = getSolidAngle(); + float oldSolidAngle = getLODAngleDeg(); float targetFPS = getLODDecreaseFPS(); float targetPeriod = 1.0f / targetFPS; @@ -89,29 +85,44 @@ void LODManager::autoAdjustLOD(float realTimeDelta) { static uint64_t lastTime = usecTimestampNow(); uint64_t now = usecTimestampNow(); auto dt = (float) ((now - lastTime) / double(USECS_PER_MSEC)); - if (dt < targetPeriod * _pid.w) return; + if (dt < targetPeriod * _pidCoefs.w) return; float deltaFPS = currentFPS - getLODDecreaseFPS(); lastTime = now; - auto previous_error = 0.f; - auto integral = 0.f; + auto previous_error = _pidHistory.x; + auto previous_integral = _pidHistory.y; auto error = getLODDecreaseFPS() - currentFPS; - integral = integral + error * dt; + auto integral = previous_integral + error * dt; auto derivative = (error - previous_error) / dt; - auto output = Kp * error + Ki * integral + Kd * derivative; - previous_error = error; + _pidHistory.x = error; + _pidHistory.y = integral; + _pidHistory.z = derivative; + + auto Kp = _pidCoefs.x; + auto Ki = _pidCoefs.y; + auto Kd = _pidCoefs.z; + + _pidOutputs.x = Kp * error; + _pidOutputs.y = Ki * integral; + _pidOutputs.z = Kd * derivative; + + auto output = _pidOutputs.x + _pidOutputs.y + _pidOutputs.z; + + _pidOutputs.w = output; auto newSolidAngle = oldSolidAngle + output; - newSolidAngle = std::max( 0.5f, std::min(newSolidAngle, 90.f)); + setLODAngleDeg(newSolidAngle); - auto halTan = glm::tan(glm::radians(newSolidAngle * 0.5f)); + //newSolidAngle = std::max( 0.5f, std::min(newSolidAngle, 90.f)); - auto octreeSizeScale = TREE_SCALE * OCTREE_TO_MESH_RATIO / halTan; - _octreeSizeScale = octreeSizeScale; + //auto halTan = glm::tan(glm::radians(newSolidAngle * 0.5f)); + + //auto octreeSizeScale = TREE_SCALE * OCTREE_TO_MESH_RATIO / halTan; + // _octreeSizeScale = octreeSizeScale; /* if (currentFPS < getLODDecreaseFPS()) { if (now > _decreaseFPSExpiry) { @@ -363,36 +374,57 @@ float LODManager::getWorldDetailQuality() const { } -float LODManager::getSolidAngleHalfTan() const { +float LODManager::getLODAngleHalfTan() const { return getPerspectiveAccuracyAngleTan(_octreeSizeScale, _boundaryLevelAdjust); } - -float LODManager::getSolidAngle() const { - return glm::degrees(2.0 * atan(getSolidAngleHalfTan())); +float LODManager::getLODAngle() const { + return 2.0f * atan(getLODAngleHalfTan()); +} +float LODManager::getLODAngleDeg() const { + return glm::degrees(getLODAngle()); } +void LODManager::setLODAngleDeg(float lodAngle) { + auto newSolidAngle = std::max(0.5f, std::min(lodAngle, 90.f)); + auto halTan = glm::tan(glm::radians(newSolidAngle * 0.5f)); + auto octreeSizeScale = TREE_SCALE * OCTREE_TO_MESH_RATIO / halTan; + setOctreeSizeScale(octreeSizeScale); +} float LODManager::getPidKp() const { - return _pid.x; + return _pidCoefs.x; } float LODManager::getPidKi() const { - return _pid.y; + return _pidCoefs.y; } float LODManager::getPidKd() const { - return _pid.z; + return _pidCoefs.z; } float LODManager::getPidT() const { - return _pid.w; + return _pidCoefs.w; } void LODManager::setPidKp(float k) { - _pid.x = k; + _pidCoefs.x = k; } void LODManager::setPidKi(float k) { - _pid.y = k; + _pidCoefs.y = k; } void LODManager::setPidKd(float k) { - _pid.z = k; + _pidCoefs.z = k; } void LODManager::setPidT(float t) { - _pid.w = t; + _pidCoefs.w = t; } + +float LODManager::getPidOp() const { + return _pidOutputs.x; +} +float LODManager::getPidOi() const { + return _pidOutputs.y; +} +float LODManager::getPidOd() const { + return _pidOutputs.z; +} +float LODManager::getPidO() const { + return _pidOutputs.w; +} \ No newline at end of file diff --git a/interface/src/LODManager.h b/interface/src/LODManager.h index b2e324a820..e4ca9912fb 100644 --- a/interface/src/LODManager.h +++ b/interface/src/LODManager.h @@ -69,14 +69,17 @@ class LODManager : public QObject, public Dependency { Q_PROPERTY(float worldDetailQuality READ getWorldDetailQuality WRITE setWorldDetailQuality NOTIFY worldDetailQualityChanged) - Q_PROPERTY(float solidAngleHalfTan READ getSolidAngleHalfTan) - Q_PROPERTY(float solidAngle READ getSolidAngle) + Q_PROPERTY(float lodAngleDeg READ getLODAngleDeg WRITE setLODAngleDeg) Q_PROPERTY(float pidKp READ getPidKp WRITE setPidKp) Q_PROPERTY(float pidKi READ getPidKi WRITE setPidKi) Q_PROPERTY(float pidKd READ getPidKd WRITE setPidKd) Q_PROPERTY(float pidT READ getPidT WRITE setPidT) + Q_PROPERTY(float pidOp READ getPidOp) + Q_PROPERTY(float pidOi READ getPidOi) + Q_PROPERTY(float pidOd READ getPidOd) + Q_PROPERTY(float pidO READ getPidO) public: @@ -187,14 +190,17 @@ public: float getAverageRenderTime() const { return _avgRenderTime; }; float getMaxTheoreticalFPS() const { return (float)MSECS_PER_SECOND / _avgRenderTime; }; + float getLODLevel() const; void setLODLevel(float level); void setWorldDetailQuality(float quality); float getWorldDetailQuality() const; - float getSolidAngleHalfTan() const; - float getSolidAngle() const; + float getLODAngleDeg() const; + void setLODAngleDeg(float lodAngle); + float getLODAngleHalfTan() const; + float getLODAngle() const; float getPidKp() const; float getPidKi() const; @@ -205,6 +211,11 @@ public: void setPidKd(float k); void setPidT(float t); + float getPidOp() const; + float getPidOi() const; + float getPidOd() const; + float getPidO() const; + signals: /**jsdoc @@ -237,7 +248,9 @@ private: float _octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE; int _boundaryLevelAdjust = 0; - glm::vec4 _pid{ 0.06f, 0.005f, 0.01f, 4.0f }; + glm::vec4 _pidCoefs{ 0.1526f, 0.00000015f, 15.f, 4.0f }; + glm::vec4 _pidHistory{ 0.0f }; + glm::vec4 _pidOutputs{ 0.0f }; uint64_t _decreaseFPSExpiry { 0 }; uint64_t _increaseFPSExpiry { 0 }; diff --git a/scripts/developer/utilities/render/configSlider/RichSlider.qml b/scripts/developer/utilities/render/configSlider/RichSlider.qml index 1613cac1b4..01b14f3d48 100644 --- a/scripts/developer/utilities/render/configSlider/RichSlider.qml +++ b/scripts/developer/utilities/render/configSlider/RichSlider.qml @@ -29,6 +29,7 @@ Item { property var labelAreaWidthScale: 0.5 property bool integral: false + property var numDigits: 2 property var valueVarSetter: defaultSet property alias valueVar : sliderControl.value @@ -71,7 +72,7 @@ Item { HifiControls.Label { id: labelValue enabled: root.showValue - text: sliderControl.value.toFixed(root.integral ? 0 : 2) + text: sliderControl.value.toFixed(root.integral ? 0 : root.numDigits) anchors.right: labelControl.right anchors.rightMargin: 5 anchors.verticalCenter: root.verticalCenter diff --git a/scripts/developer/utilities/render/lod.qml b/scripts/developer/utilities/render/lod.qml index 1ca9b68de2..90e7573fda 100644 --- a/scripts/developer/utilities/render/lod.qml +++ b/scripts/developer/utilities/render/lod.qml @@ -68,11 +68,11 @@ Item { RichSlider { visible: !LODManager.automaticLODAdjust showLabel: true - label: "LOD Level" - valueVar: LODManager["lodLevel"] - valueVarSetter: (function (v) { LODManager["lodLevel"] = v }) - max: 1.0 - min: 0.0 + label: "LOD Angle [deg]" + valueVar: LODManager["lodAngleDeg"] + valueVarSetter: (function (v) { LODManager["lodAngleDeg"] = v }) + max: 90.0 + min: 0.5 integral: false anchors.left: parent.left @@ -85,9 +85,10 @@ Item { label: "LOD PID Kp" valueVar: LODManager["pidKp"] valueVarSetter: (function (v) { LODManager["pidKp"] = v }) - max: 1.0 + max: 0.2 min: 0.0 integral: false + numDigits: 3 anchors.left: parent.left anchors.right: parent.right @@ -98,9 +99,10 @@ Item { label: "LOD PID Ki" valueVar: LODManager["pidKi"] valueVarSetter: (function (v) { LODManager["pidKi"] = v }) - max: 0.02 + max: 0.000005 min: 0.0 integral: false + numDigits: 8 anchors.left: parent.left anchors.right: parent.right @@ -111,9 +113,10 @@ Item { label: "LOD PID Kd" valueVar: LODManager["pidKd"] valueVarSetter: (function (v) { LODManager["pidKd"] = v }) - max: 0.1 + max: 10.0 min: 0.0 integral: false + numDigits: 3 anchors.left: parent.left anchors.right: parent.right @@ -124,9 +127,9 @@ Item { label: "LOD PID Num T" valueVar: LODManager["pidT"] valueVarSetter: (function (v) { LODManager["pidT"] = v }) - max: 5.0 + max: 10.0 min: 0.0 - integral: false + integral: true anchors.left: parent.left anchors.right: parent.right @@ -199,34 +202,43 @@ Item { ] } PlotPerf { - title: "LOD" + title: "LOD Angle" height: parent.evalEvenHeight() object: LODManager - valueScale: 0.1 - valueUnit: "" + valueScale: 1.0 + valueUnit: "deg" plots: [ { - prop: "lodLevel", - label: "LOD", + prop: "lodAngleDeg", + label: "LOD Angle", color: "#9999FF" } ] } PlotPerf { - title: "Solid Angle" + title: "PID Output" height: parent.evalEvenHeight() object: LODManager valueScale: 1.0 valueUnit: "deg" - //valueNumDigits: 0 plots: [ { - prop: "solidAngle", - label: "Solid Angle", + prop: "pidOp", + label: "Op", color: "#9999FF" + }, + { + prop: "pidOi", + label: "Oi", + color: "#FFFFFF" + }, + { + prop: "pidOd", + label: "Od", + color: "#FF6666" } ] - } + } Separator { id: bottomLine } From 4b7f6a346fecaf0b8b9e508254dfff805498227f Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Tue, 28 Aug 2018 16:21:47 -0700 Subject: [PATCH 138/545] Use AvatarData::getClientGlobalPosition() for position in priority queue It looks like it's the same as world position with the avatar mixer. Also use one time stamp for current time in priority queue; use std::chrono for some other timestamps in hope that it's faster. Fix priority-code logic bug. --- .../src/avatars/AvatarMixerSlave.cpp | 26 +++++++++---------- libraries/shared/src/PrioritySortUtil.h | 12 ++++++--- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index 50ddcec92b..f0c291b2c2 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -33,6 +34,8 @@ #include "AvatarMixer.h" #include "AvatarMixerClientData.h" +namespace chrono = std::chrono; + void AvatarMixerSlave::configure(ConstIter begin, ConstIter end) { _begin = begin; _end = end; @@ -301,9 +304,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) }; // Temporary info about the avatars we're sending: std::vector avatarsToSort; - //std::unordered_map avatarDataToNodes; - //std::unordered_map avatarDataToNodesShared; - //std::unordered_map avatarEncodeTimes; + avatarsToSort.reserve(_end - _begin); std::for_each(_begin, _end, [&](const SharedNodePointer& otherNode) { Node* otherNodeRaw = otherNode.data(); // make sure this is an agent that we have avatar data for before considering it for inclusion @@ -313,9 +314,6 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) AvatarData* otherAvatar = otherNodeData->getAvatarSharedPointer().get(); - //avatarsToSort.push_back(otherAvatar); - //avatarDataToNodes[otherAvatar] = otherNode.data(); - //avatarDataToNodesShared[otherAvatar] = otherNode; auto lastEncodeTime = nodeData->getLastOtherAvatarEncodeTime(otherAvatar->getSessionUUID()); avatarsToSort.emplace_back(AvatarSortData(otherNode, otherAvatar, lastEncodeTime)); } @@ -326,7 +324,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) SortableAvatar() = delete; SortableAvatar(const AvatarData* avatar, const Node* avatarNode, uint64_t lastEncodeTime) : _avatar(avatar), _node(avatarNode), _lastEncodeTime(lastEncodeTime) {} - glm::vec3 getPosition() const override { return _avatar->getWorldPosition(); } + glm::vec3 getPosition() const override { return _avatar->getClientGlobalPosition(); } float getRadius() const override { glm::vec3 nodeBoxHalfScale = (_avatar->getWorldPosition() - _avatar->getGlobalBoundingBoxCorner() * _avatar->getSensorToWorldScale()); return glm::max(nodeBoxHalfScale.x, glm::max(nodeBoxHalfScale.y, nodeBoxHalfScale.z)); @@ -452,7 +450,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) int minimRemainingAvatarBytes = minimumBytesPerAvatar * remainingAvatars; bool overBudget = (identityBytesSent + numAvatarDataBytes + minimRemainingAvatarBytes) > maxAvatarBytesPerFrame; - quint64 startAvatarDataPacking = usecTimestampNow(); + auto startAvatarDataPacking = chrono::high_resolution_clock::now(); ++numOtherAvatars; @@ -504,12 +502,13 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) AvatarDataPacket::HasFlags hasFlagsOut; // the result of the toByteArray bool dropFaceTracking = false; - quint64 start = usecTimestampNow(); + auto startSerialize = chrono::high_resolution_clock::now(); QByteArray bytes = otherAvatar->toByteArray(detail, lastEncodeForOther, lastSentJointsForOther, hasFlagsOut, dropFaceTracking, distanceAdjust, viewerPosition, &lastSentJointsForOther); - quint64 end = usecTimestampNow(); - _stats.toByteArrayElapsedTime += (end - start); + auto endSerialize = chrono::high_resolution_clock::now(); + _stats.toByteArrayElapsedTime += + (quint64) chrono::duration_cast(endSerialize - startSerialize).count(); static auto maxAvatarDataBytes = avatarPacketList->getMaxSegmentSize() - NUM_BYTES_RFC4122_UUID; if (bytes.size() > maxAvatarDataBytes) { @@ -558,8 +557,9 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) avatarPacketList->endSegment(); - quint64 endAvatarDataPacking = usecTimestampNow(); - _stats.avatarDataPackingElapsedTime += (endAvatarDataPacking - startAvatarDataPacking); + auto endAvatarDataPacking = chrono::high_resolution_clock::now(); + _stats.avatarDataPackingElapsedTime += + (quint64) chrono::duration_cast(endAvatarDataPacking - startAvatarDataPacking).count(); // use helper to add any changed traits to our packet list traitBytesSent += addChangedTraitsToBulkPacket(nodeData, otherNodeData, *traitsPacketList); diff --git a/libraries/shared/src/PrioritySortUtil.h b/libraries/shared/src/PrioritySortUtil.h index 34ec074d45..a2be5fadcd 100644 --- a/libraries/shared/src/PrioritySortUtil.h +++ b/libraries/shared/src/PrioritySortUtil.h @@ -87,6 +87,7 @@ namespace PrioritySortUtil { PriorityQueue(const ConicalViewFrustums& views) : _views(views) { } PriorityQueue(const ConicalViewFrustums& views, float angularWeight, float centerWeight, float ageWeight) : _views(views), _angularWeight(angularWeight), _centerWeight(centerWeight), _ageWeight(ageWeight) + , _usecCurrentTime(usecTimestampNow()) { } void setViews(const ConicalViewFrustums& views) { _views = views; } @@ -95,6 +96,7 @@ namespace PrioritySortUtil { _angularWeight = angularWeight; _centerWeight = centerWeight; _ageWeight = ageWeight; + _usecCurrentTime = usecTimestampNow(); } size_t size() const { return _queue.size(); } @@ -129,16 +131,17 @@ namespace PrioritySortUtil { glm::vec3 offset = position - view.getPosition(); float distance = glm::length(offset) + 0.001f; // add 1mm to avoid divide by zero const float MIN_RADIUS = 0.1f; // WORKAROUND for zero size objects (we still want them to sort by distance) - float radius = glm::min(thing.getRadius(), MIN_RADIUS); + float radius = glm::max(thing.getRadius(), MIN_RADIUS); + // Other item's angle from view centre: float cosineAngle = (glm::dot(offset, view.getDirection()) / distance); - float age = (float)(usecTimestampNow() - thing.getTimestamp()); + float age = (float)(_usecCurrentTime - thing.getTimestamp()); - // we modulatate "age" drift rate by the cosineAngle term to make periphrial objects sort forward + // we modulate "age" drift rate by the cosineAngle term to make peripheral objects sort forward // at a reduced rate but we don't want the "age" term to go zero or negative so we clamp it const float MIN_COSINE_ANGLE_FACTOR = 0.1f; float cosineAngleFactor = glm::max(cosineAngle, MIN_COSINE_ANGLE_FACTOR); - float priority = _angularWeight * glm::max(radius, MIN_RADIUS) / distance + float priority = _angularWeight * radius / distance + _centerWeight * cosineAngle + _ageWeight * cosineAngleFactor * age; @@ -157,6 +160,7 @@ namespace PrioritySortUtil { float _angularWeight { DEFAULT_ANGULAR_COEF }; float _centerWeight { DEFAULT_CENTER_COEF }; float _ageWeight { DEFAULT_AGE_COEF }; + quint64 _usecCurrentTime { 0 }; }; } // namespace PrioritySortUtil From 223f86108f62b6b89a53c2542f2c26a7cd3cc957 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Tue, 28 Aug 2018 17:34:48 -0700 Subject: [PATCH 139/545] adding debugging stuff --- libraries/networking/src/AddressManager.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 0b69fda3fa..732a2d7963 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -48,6 +48,8 @@ QString AddressManager::getProtocol() const { QUrl AddressManager::currentAddress(bool domainOnly) const { QUrl hifiURL = _domainURL; + auto urlStr = hifiURL.toString().toStdString(); + if (!domainOnly && hifiURL.scheme() == URL_SCHEME_HIFI) { hifiURL.setPath(currentPath()); } From 37b4cf6223c2a8ce9cc20b99a4f014d53d8480dc Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 28 Aug 2018 17:39:35 -0700 Subject: [PATCH 140/545] Picking pid values --- interface/src/Application.cpp | 3 ++- interface/src/LODManager.cpp | 12 +++++---- interface/src/LODManager.h | 8 ++++-- .../utilities/lib/plotperf/PlotPerf.qml | 27 ++++++++++++++++++- scripts/developer/utilities/render/lod.qml | 2 +- 5 files changed, 42 insertions(+), 10 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e7b17b3d69..fc62b01ca6 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5028,8 +5028,9 @@ void Application::updateLOD(float deltaTime) const { float presentTime = getActiveDisplayPlugin()->getAveragePresentTime(); float engineRunTime = (float)(_renderEngine->getConfiguration().get()->getCPURunTime()); float gpuTime = getGPUContext()->getFrameTimerGPUAverage(); + float batchTime = getGPUContext()->getFrameTimerBatchAverage(); auto lodManager = DependencyManager::get(); - lodManager->setRenderTimes(presentTime, engineRunTime, gpuTime); + lodManager->setRenderTimes(presentTime, engineRunTime, batchTime, gpuTime); lodManager->autoAdjustLOD(deltaTime); } else { DependencyManager::get()->resetLODAdjust(); diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index 7f99e74a2a..a32f3472ab 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -58,18 +58,21 @@ const uint64_t LOD_AUTO_ADJUST_PERIOD = 4 * (uint64_t)(LOD_ADJUST_RUNNING_AVG_TI const float LOD_AUTO_ADJUST_DECREMENT_FACTOR = 0.8f; const float LOD_AUTO_ADJUST_INCREMENT_FACTOR = 1.2f; -void LODManager::setRenderTimes(float presentTime, float engineRunTime, float gpuTime) { +void LODManager::setRenderTimes(float presentTime, float engineRunTime, float batchTime, float gpuTime) { _presentTime = presentTime; _engineRunTime = engineRunTime; + _batchTime = batchTime; _gpuTime = gpuTime; } void LODManager::autoAdjustLOD(float realTimeDelta) { + // float maxRenderTime = glm::max(glm::max(_presentTime, _engineRunTime), _gpuTime); float maxRenderTime = glm::max(glm::max(_presentTime, _engineRunTime), _gpuTime); // compute time-weighted running average maxRenderTime // Note: we MUST clamp the blend to 1.0 for stability float blend = (realTimeDelta < LOD_ADJUST_RUNNING_AVG_TIMESCALE) ? realTimeDelta / LOD_ADJUST_RUNNING_AVG_TIMESCALE : 1.0f; _avgRenderTime = (1.0f - blend) * _avgRenderTime + blend * maxRenderTime; // msec + // _avgRenderTime = maxRenderTime; if (!_automaticLODAdjust || _avgRenderTime == 0.0f) { // early exit return; @@ -78,7 +81,7 @@ void LODManager::autoAdjustLOD(float realTimeDelta) { float oldOctreeSizeScale = _octreeSizeScale; float oldSolidAngle = getLODAngleDeg(); - float targetFPS = getLODDecreaseFPS(); + float targetFPS = 0.5 * (getLODDecreaseFPS() + getLODIncreaseFPS()); float targetPeriod = 1.0f / targetFPS; float currentFPS = (float)MSECS_PER_SECOND / _avgRenderTime; @@ -87,13 +90,12 @@ void LODManager::autoAdjustLOD(float realTimeDelta) { auto dt = (float) ((now - lastTime) / double(USECS_PER_MSEC)); if (dt < targetPeriod * _pidCoefs.w) return; - float deltaFPS = currentFPS - getLODDecreaseFPS(); - lastTime = now; auto previous_error = _pidHistory.x; auto previous_integral = _pidHistory.y; - auto error = getLODDecreaseFPS() - currentFPS; + auto error = (targetFPS - currentFPS) / targetFPS; + error = glm::clamp(error, -1.0f, 1.0f); auto integral = previous_integral + error * dt; auto derivative = (error - previous_error) / dt; diff --git a/interface/src/LODManager.h b/interface/src/LODManager.h index e4ca9912fb..74075f2400 100644 --- a/interface/src/LODManager.h +++ b/interface/src/LODManager.h @@ -59,6 +59,7 @@ class LODManager : public QObject, public Dependency { Q_PROPERTY(float presentTime READ getPresentTime) Q_PROPERTY(float engineRunTime READ getEngineRunTime) + Q_PROPERTY(float batchTime READ getBatchTime) Q_PROPERTY(float gpuTime READ getGPUTime) Q_PROPERTY(float avgRenderTime READ getAverageRenderTime) Q_PROPERTY(float fps READ getMaxTheoreticalFPS) @@ -178,10 +179,11 @@ public: float getPresentTime() const { return _presentTime; } float getEngineRunTime() const { return _engineRunTime; } + float getBatchTime() const { return _batchTime; } float getGPUTime() const { return _gpuTime; } static bool shouldRender(const RenderArgs* args, const AABox& bounds); - void setRenderTimes(float presentTime, float engineRunTime, float gpuTime); + void setRenderTimes(float presentTime, float engineRunTime, float batchTime, float gpuTime); void autoAdjustLOD(float realTimeDelta); void loadSettings(); @@ -240,7 +242,9 @@ private: bool _automaticLODAdjust = true; float _presentTime { 0.0f }; // msec float _engineRunTime { 0.0f }; // msec + float _batchTime{ 0.0f }; // msec float _gpuTime { 0.0f }; // msec + float _avgRenderTime { 0.0f }; // msec float _desktopMaxRenderTime { DEFAULT_DESKTOP_MAX_RENDER_TIME }; float _hmdMaxRenderTime { DEFAULT_HMD_MAX_RENDER_TIME }; @@ -248,7 +252,7 @@ private: float _octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE; int _boundaryLevelAdjust = 0; - glm::vec4 _pidCoefs{ 0.1526f, 0.00000015f, 15.f, 4.0f }; + glm::vec4 _pidCoefs{ 4.0f, 0.0000000f, 0.f, 4.0f }; glm::vec4 _pidHistory{ 0.0f }; glm::vec4 _pidOutputs{ 0.0f }; diff --git a/scripts/developer/utilities/lib/plotperf/PlotPerf.qml b/scripts/developer/utilities/lib/plotperf/PlotPerf.qml index 916c9cae55..99ff5f712e 100644 --- a/scripts/developer/utilities/lib/plotperf/PlotPerf.qml +++ b/scripts/developer/utilities/lib/plotperf/PlotPerf.qml @@ -48,6 +48,7 @@ Item { property var valueMax : 1 + property var valueMin : 0 property var _values property var tick : 0 @@ -90,6 +91,11 @@ Item { _values[i].valueMax *= 0.25 // Fast reduce the max value as we click } } + function resetMin() { + for (var i = 0; i < _values.length; i++) { + _values[i].valueMin *= 0.25 // Fast reduce the min value as we click + } + } function pullFreshValues() { // Wait until values are created to begin pulling @@ -99,6 +105,7 @@ Item { tick++; var currentValueMax = 0 + var currentValueMin = 0 for (var i = 0; i < _values.length; i++) { var currentVal = (+_values[i].object[_values[i].value]) * _values[i].scale; @@ -112,26 +119,44 @@ Item { _values[i].valueMax *= 0.99 _values[i].numSamplesConstantMax = 0 } + if (lostValue <= _values[i].valueMin) { + _values[i].valueMin *= 0.99 + _values[i].numSamplesConstantMin = 0 + } } if (_values[i].valueMax < currentVal) { _values[i].valueMax = currentVal; _values[i].numSamplesConstantMax = 0 } + if (_values[i].valueMin < currentVal) { + _values[i].valueMin = currentVal; + _values[i].numSamplesConstantMin = 0 + } if (_values[i].numSamplesConstantMax > VALUE_HISTORY_SIZE) { _values[i].numSamplesConstantMax = 0 _values[i].valueMax *= 0.95 // lower slowly the current max if no new above max since a while } - + if (_values[i].numSamplesConstantMin > VALUE_HISTORY_SIZE) { + _values[i].numSamplesConstantMin = 0 + _values[i].valueMin *= 0.95 // lower slowly the current min if no new above min since a while + } + if (currentValueMax < _values[i].valueMax) { currentValueMax = _values[i].valueMax } + if (currentValueMin < _values[i].valueMin) { + currentValueMin = _values[i].valueMin + } } if ((valueMax < currentValueMax) || (tick % VALUE_HISTORY_SIZE == 0)) { valueMax = currentValueMax; } + if ((valueMin < currentValueMin) || (tick % VALUE_HISTORY_SIZE == 0)) { + valueMin = currentValueMin; + } mycanvas.requestPaint() } diff --git a/scripts/developer/utilities/render/lod.qml b/scripts/developer/utilities/render/lod.qml index 90e7573fda..fe284fec93 100644 --- a/scripts/developer/utilities/render/lod.qml +++ b/scripts/developer/utilities/render/lod.qml @@ -85,7 +85,7 @@ Item { label: "LOD PID Kp" valueVar: LODManager["pidKp"] valueVarSetter: (function (v) { LODManager["pidKp"] = v }) - max: 0.2 + max: 2.0 min: 0.0 integral: false numDigits: 3 From ee33f5dc97610c96a8e29b89049bc9adc608311e Mon Sep 17 00:00:00 2001 From: Angus Antley Date: Wed, 29 Aug 2018 01:57:49 +0100 Subject: [PATCH 141/545] normalize the hip hand vector in getSpine2RotationRigSpace, made computeHandAzimuth a const function that returns a vec2 --- interface/src/avatar/MyAvatar.cpp | 36 +++++++++++++----------- interface/src/avatar/MyAvatar.h | 2 +- interface/src/avatar/MySkeletonModel.cpp | 34 +++++++++++----------- 3 files changed, 38 insertions(+), 34 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 32822fc1b9..75becd2c6d 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -91,8 +91,6 @@ const float MIN_SCALE_CHANGED_DELTA = 0.001f; const int MODE_READINGS_RING_BUFFER_SIZE = 500; const float CENTIMETERS_PER_METER = 100.0f; -#define DEBUG_DRAW_HMD_MOVING_AVERAGE - MyAvatar::MyAvatar(QThread* thread) : Avatar(thread), _yawSpeed(YAW_SPEED_DEFAULT), @@ -450,6 +448,7 @@ void MyAvatar::update(float deltaTime) { const float PERCENTAGE_WEIGHT_HEAD_VS_SHOULDERS_AZIMUTH = 0.0f; // 100 percent shoulders float tau = deltaTime / HMD_FACING_TIMESCALE; + setHipToHandController(computeHandAzimuth()); // put the average hand azimuth into sensor space. // then mix it with head facing direction to determine rotation recenter @@ -465,7 +464,7 @@ void MyAvatar::update(float deltaTime) { glm::vec2 headFacingPlusHandHipAzimuthMix = lerp(normedHandHipAzimuthSensorSpace, _headControllerFacing, PERCENTAGE_WEIGHT_HEAD_VS_SHOULDERS_AZIMUTH); _headControllerFacingMovingAverage = lerp(_headControllerFacingMovingAverage, headFacingPlusHandHipAzimuthMix, tau); } else { - _headControllerFacingMovingAverage = _headControllerFacing; + _headControllerFacingMovingAverage = lerp(_headControllerFacingMovingAverage, _headControllerFacing, tau); } if (_smoothOrientationTimer < SMOOTH_TIME_ORIENTATION) { @@ -478,10 +477,8 @@ void MyAvatar::update(float deltaTime) { _recentModeReadings.insert(newHeightReadingInCentimeters); setCurrentStandingHeight(computeStandingHeightMode(getControllerPoseInAvatarFrame(controller::Action::HEAD))); setAverageHeadRotation(computeAverageHeadRotation(getControllerPoseInAvatarFrame(controller::Action::HEAD))); - computeHandAzimuth(); -#ifdef DEBUG_DRAW_HMD_MOVING_AVERAGE - if (_drawAverageFacingEnabled) { + if (_drawAverageFacingEnabled) { auto sensorHeadPose = getControllerPoseInSensorFrame(controller::Action::HEAD); glm::vec3 worldHeadPos = transformPoint(getSensorToWorldMatrix(), sensorHeadPose.getTranslation()); glm::vec3 worldFacingAverage = transformVectorFast(getSensorToWorldMatrix(), glm::vec3(_headControllerFacingMovingAverage.x, 0.0f, _headControllerFacingMovingAverage.y)); @@ -493,12 +490,11 @@ void MyAvatar::update(float deltaTime) { glm::vec3 handAzimuthMidpoint = transformPoint(getTransform().getMatrix(), glm::vec3(_hipToHandController.x, 0.0f, _hipToHandController.y)); DebugDraw::getInstance().drawRay(getWorldPosition(), handAzimuthMidpoint, glm::vec4(0.0f, 1.0f, 1.0f, 1.0f)); } -#endif if (_goToPending) { setWorldPosition(_goToPosition); setWorldOrientation(_goToOrientation); - _headControllerFacingMovingAverage = _headControllerFacing; + _headControllerFacingMovingAverage = _headControllerFacing; // reset moving average _goToPending = false; // updateFromHMDSensorMatrix (called from paintGL) expects that the sensorToWorldMatrix is updated for any position changes // that happen between render and Application::update (which calls updateSensorToWorldMatrix to do so). @@ -822,29 +818,30 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { // Find the vector halfway between the hip to hand azimuth vectors // This midpoint hand azimuth is in Avatar space -void MyAvatar::computeHandAzimuth() { +glm::vec2 MyAvatar::computeHandAzimuth() const { auto leftHandPoseAvatarSpace = getLeftHandPose(); auto rightHandPoseAvatarSpace = getRightHandPose(); const float HALFWAY = 0.50f; + glm::vec2 latestHipToHandController = _hipToHandController; if (leftHandPoseAvatarSpace.isValid() && rightHandPoseAvatarSpace.isValid()) { // we need the old azimuth reading to prevent flipping the facing direction 180 // in the case where the hands go from being slightly less than 180 apart to slightly more than 180 apart. - vec2 oldAzimuthReading = _hipToHandController; + glm::vec2 oldAzimuthReading = _hipToHandController; if ((glm::length(glm::vec2(rightHandPoseAvatarSpace.translation.x, rightHandPoseAvatarSpace.translation.z)) > 0.0f) && (glm::length(glm::vec2(leftHandPoseAvatarSpace.translation.x, leftHandPoseAvatarSpace.translation.z)) > 0.0f)) { - _hipToHandController = lerp(glm::normalize(glm::vec2(rightHandPoseAvatarSpace.translation.x, rightHandPoseAvatarSpace.translation.z)), glm::normalize(glm::vec2(leftHandPoseAvatarSpace.translation.x, leftHandPoseAvatarSpace.translation.z)), HALFWAY); + latestHipToHandController = lerp(glm::normalize(glm::vec2(rightHandPoseAvatarSpace.translation.x, rightHandPoseAvatarSpace.translation.z)), glm::normalize(glm::vec2(leftHandPoseAvatarSpace.translation.x, leftHandPoseAvatarSpace.translation.z)), HALFWAY); } else { - _hipToHandController = glm::vec2(0.0f, -1.0f); + latestHipToHandController = glm::vec2(0.0f, -1.0f); } // check the angular distance from forward and back - float cosForwardAngle = glm::dot(_hipToHandController, oldAzimuthReading); - float cosBackwardAngle = glm::dot(_hipToHandController, -oldAzimuthReading); + float cosForwardAngle = glm::dot(latestHipToHandController, oldAzimuthReading); // if we are now closer to the 180 flip of the previous chest forward - // then we negate our computed _hipToHandController to keep the chest from flipping. - if (cosBackwardAngle > cosForwardAngle) { - _hipToHandController = -_hipToHandController; + // then we negate our computed latestHipToHandController to keep the chest from flipping. + if (cosForwardAngle < 0.0f) { + latestHipToHandController = -latestHipToHandController; } } + return latestHipToHandController; } void MyAvatar::updateJointFromController(controller::Action poseKey, ThreadSafeValueCache& matrixCache) { @@ -3380,6 +3377,11 @@ glm::mat4 MyAvatar::getSpine2RotationRigSpace() const { glm::vec3 hipToHandRigSpace = AVATAR_TO_RIG_ROTATION * glm::vec3(_hipToHandController.x, 0.0f, _hipToHandController.y); glm::vec3 u, v, w; + if (glm::length(hipToHandRigSpace) > 0.0f) { + hipToHandRigSpace = glm::normalize(hipToHandRigSpace); + } else { + hipToHandRigSpace = glm::vec3(0.0f, 0.0f, 1.0f); + } generateBasisVectors(glm::vec3(0.0f,1.0f,0.0f), hipToHandRigSpace, u, v, w); glm::mat4 spine2RigSpace(glm::vec4(w, 0.0f), glm::vec4(u, 0.0f), glm::vec4(v, 0.0f), glm::vec4(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f)); return spine2RigSpace; diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 8b5d9d8c55..f82c5b4018 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -321,7 +321,7 @@ public: void updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix); // compute the hip to hand average azimuth. - void computeHandAzimuth(); + glm::vec2 computeHandAzimuth() const; // read the location of a hand controller and save the transform void updateJointFromController(controller::Action poseKey, ThreadSafeValueCache& matrixCache); diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index e06a06cf0e..8fd7d31956 100644 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -243,23 +243,25 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { AnimPose currentSpine2Pose; AnimPose currentHeadPose; AnimPose currentHipsPose; - bool ret = _rig.getAbsoluteJointPoseInRigFrame(_rig.indexOfJoint("Spine2"), currentSpine2Pose); - bool ret1 = _rig.getAbsoluteJointPoseInRigFrame(_rig.indexOfJoint("Head"), currentHeadPose); - bool ret2 = _rig.getAbsoluteJointPoseInRigFrame(_rig.indexOfJoint("Hips"), currentHipsPose); - AnimPose rigSpaceYaw(myAvatar->getSpine2RotationRigSpace()); - glm::vec3 u, v, w; - glm::vec3 fwd = rigSpaceYaw.rot() * glm::vec3(0.0f, 0.0f, 1.0f); - glm::vec3 up = currentHeadPose.trans() - currentHipsPose.trans(); - if (glm::length(up) > 0.0f) { - up = glm::normalize(up); - } else { - up = glm::vec3(0.0f, 1.0f, 0.0f); + bool spine2Exists = _rig.getAbsoluteJointPoseInRigFrame(_rig.indexOfJoint("Spine2"), currentSpine2Pose); + bool headExists = _rig.getAbsoluteJointPoseInRigFrame(_rig.indexOfJoint("Head"), currentHeadPose); + bool hipsExists = _rig.getAbsoluteJointPoseInRigFrame(_rig.indexOfJoint("Hips"), currentHipsPose); + if (spine2Exists && headExists && hipsExists) { + AnimPose rigSpaceYaw(myAvatar->getSpine2RotationRigSpace()); + glm::vec3 u, v, w; + glm::vec3 fwd = rigSpaceYaw.rot() * glm::vec3(0.0f, 0.0f, 1.0f); + glm::vec3 up = currentHeadPose.trans() - currentHipsPose.trans(); + if (glm::length(up) > 0.0f) { + up = glm::normalize(up); + } else { + up = glm::vec3(0.0f, 1.0f, 0.0f); + } + generateBasisVectors(up, fwd, u, v, w); + AnimPose newSpinePose(glm::mat4(glm::vec4(w, 0.0f), glm::vec4(u, 0.0f), glm::vec4(v, 0.0f), glm::vec4(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f))); + currentSpine2Pose.rot() = newSpinePose.rot(); + params.primaryControllerPoses[Rig::PrimaryControllerType_Spine2] = currentSpine2Pose; + params.primaryControllerFlags[Rig::PrimaryControllerType_Spine2] = (uint8_t)Rig::ControllerFlags::Enabled | (uint8_t)Rig::ControllerFlags::Estimated; } - generateBasisVectors(up, fwd, u, v, w); - AnimPose newSpinePose(glm::mat4(glm::vec4(w, 0.0f), glm::vec4(u, 0.0f), glm::vec4(v, 0.0f), glm::vec4(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f))); - currentSpine2Pose.rot() = newSpinePose.rot(); - params.primaryControllerPoses[Rig::PrimaryControllerType_Spine2] = currentSpine2Pose; - params.primaryControllerFlags[Rig::PrimaryControllerType_Spine2] = (uint8_t)Rig::ControllerFlags::Enabled | (uint8_t)Rig::ControllerFlags::Estimated; } } else { From 442644381ad20d829459fa281b7fc5c67e959db4 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Tue, 28 Aug 2018 20:16:55 -0700 Subject: [PATCH 142/545] adding other connection refused suppressions --- interface/src/ConnectionMonitor.cpp | 4 ++-- scripts/system/notifications.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/ConnectionMonitor.cpp b/interface/src/ConnectionMonitor.cpp index 8deddbda82..7d535d9eaf 100644 --- a/interface/src/ConnectionMonitor.cpp +++ b/interface/src/ConnectionMonitor.cpp @@ -38,7 +38,7 @@ void ConnectionMonitor::init() { connect(&_timer, &QTimer::timeout, this, []() { qDebug() << "ConnectionMonitor: Showing connection failure window"; - DependencyManager::get()->setDomainConnectionFailureVisibility(true); + //DependencyManager::get()->setDomainConnectionFailureVisibility(true); }); } @@ -48,5 +48,5 @@ void ConnectionMonitor::startTimer() { void ConnectionMonitor::stopTimer() { _timer.stop(); - DependencyManager::get()->setDomainConnectionFailureVisibility(false); + //DependencyManager::get()->setDomainConnectionFailureVisibility(false); } diff --git a/scripts/system/notifications.js b/scripts/system/notifications.js index 0778e2a44b..13d500b909 100644 --- a/scripts/system/notifications.js +++ b/scripts/system/notifications.js @@ -624,7 +624,7 @@ Controller.keyReleaseEvent.connect(keyReleaseEvent); Script.update.connect(update); Script.scriptEnding.connect(scriptEnding); - Window.domainConnectionRefused.connect(onDomainConnectionRefused); + //Window.domainConnectionRefused.connect(onDomainConnectionRefused); Window.stillSnapshotTaken.connect(onSnapshotTaken); Window.snapshot360Taken.connect(onSnapshotTaken); Window.processingGifStarted.connect(processingGif); From bf348f43aa55d790423f6e5a828e0372e9843f90 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Wed, 29 Aug 2018 09:55:54 -0700 Subject: [PATCH 143/545] Prepare for runtime CPU dispatch of all SIMD functions --- libraries/audio/src/AudioHRTF.cpp | 54 ++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/libraries/audio/src/AudioHRTF.cpp b/libraries/audio/src/AudioHRTF.cpp index 23adcde0c5..aef4ef3326 100644 --- a/libraries/audio/src/AudioHRTF.cpp +++ b/libraries/audio/src/AudioHRTF.cpp @@ -276,23 +276,8 @@ static void FIR_1x4_SSE(float* src, float* dst0, float* dst1, float* dst2, float } } -// -// Runtime CPU dispatch -// - -#include "CPUDetect.h" - -void FIR_1x4_AVX2(float* src, float* dst0, float* dst1, float* dst2, float* dst3, float coef[4][HRTF_TAPS], int numFrames); -void FIR_1x4_AVX512(float* src, float* dst0, float* dst1, float* dst2, float* dst3, float coef[4][HRTF_TAPS], int numFrames); - -static void FIR_1x4(float* src, float* dst0, float* dst1, float* dst2, float* dst3, float coef[4][HRTF_TAPS], int numFrames) { - - static auto f = cpuSupportsAVX512() ? FIR_1x4_AVX512 : (cpuSupportsAVX2() ? FIR_1x4_AVX2 : FIR_1x4_SSE); - (*f)(src, dst0, dst1, dst2, dst3, coef, numFrames); // dispatch -} - // 4 channel planar to interleaved -static void interleave_4x4(float* src0, float* src1, float* src2, float* src3, float* dst, int numFrames) { +static void interleave_4x4_SSE(float* src0, float* src1, float* src2, float* src3, float* dst, int numFrames) { assert(numFrames % 4 == 0); @@ -323,7 +308,7 @@ static void interleave_4x4(float* src0, float* src1, float* src2, float* src3, f // process 2 cascaded biquads on 4 channels (interleaved) // biquads computed in parallel, by adding one sample of delay -static void biquad2_4x4(float* src, float* dst, float coef[5][8], float state[3][8], int numFrames) { +static void biquad2_4x4_SSE(float* src, float* dst, float coef[5][8], float state[3][8], int numFrames) { // enable flush-to-zero mode to prevent denormals unsigned int ftz = _MM_GET_FLUSH_ZERO_MODE(); @@ -388,7 +373,7 @@ static void biquad2_4x4(float* src, float* dst, float coef[5][8], float state[3] } // crossfade 4 inputs into 2 outputs with accumulation (interleaved) -static void crossfade_4x2(float* src, float* dst, const float* win, int numFrames) { +static void crossfade_4x2_SSE(float* src, float* dst, const float* win, int numFrames) { assert(numFrames % 4 == 0); @@ -435,7 +420,7 @@ static void crossfade_4x2(float* src, float* dst, const float* win, int numFrame } // linear interpolation with gain -static void interpolate(float* dst, const float* src0, const float* src1, float frac, float gain) { +static void interpolate_SSE(float* dst, const float* src0, const float* src1, float frac, float gain) { __m128 f0 = _mm_set1_ps(gain * (1.0f - frac)); __m128 f1 = _mm_set1_ps(gain * frac); @@ -453,6 +438,37 @@ static void interpolate(float* dst, const float* src0, const float* src1, float } } +// +// Runtime CPU dispatch +// + +#include "CPUDetect.h" + +void FIR_1x4_AVX2(float* src, float* dst0, float* dst1, float* dst2, float* dst3, float coef[4][HRTF_TAPS], int numFrames); +void FIR_1x4_AVX512(float* src, float* dst0, float* dst1, float* dst2, float* dst3, float coef[4][HRTF_TAPS], int numFrames); + +static void FIR_1x4(float* src, float* dst0, float* dst1, float* dst2, float* dst3, float coef[4][HRTF_TAPS], int numFrames) { + + static auto f = cpuSupportsAVX512() ? FIR_1x4_AVX512 : (cpuSupportsAVX2() ? FIR_1x4_AVX2 : FIR_1x4_SSE); + (*f)(src, dst0, dst1, dst2, dst3, coef, numFrames); // dispatch +} + +static void interleave_4x4(float* src0, float* src1, float* src2, float* src3, float* dst, int numFrames) { + interleave_4x4_SSE(src0, src1, src2, src3, dst, numFrames); +} + +static void biquad2_4x4(float* src, float* dst, float coef[5][8], float state[3][8], int numFrames) { + biquad2_4x4_SSE(src, dst, coef, state, numFrames); +} + +static void crossfade_4x2(float* src, float* dst, const float* win, int numFrames) { + crossfade_4x2_SSE(src, dst, win, numFrames); +} + +static void interpolate(float* dst, const float* src0, const float* src1, float frac, float gain) { + interpolate_SSE(dst, src0, src1, frac, gain); +} + #else // portable reference code // 1 channel input, 4 channel output From 6f151ad2837cb252dd8ea16c5baa3e415ca23363 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Wed, 29 Aug 2018 10:03:40 -0700 Subject: [PATCH 144/545] Consistent parameter order for SIMD functions --- libraries/audio/src/AudioHRTF.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/audio/src/AudioHRTF.cpp b/libraries/audio/src/AudioHRTF.cpp index aef4ef3326..20d782a414 100644 --- a/libraries/audio/src/AudioHRTF.cpp +++ b/libraries/audio/src/AudioHRTF.cpp @@ -420,7 +420,7 @@ static void crossfade_4x2_SSE(float* src, float* dst, const float* win, int numF } // linear interpolation with gain -static void interpolate_SSE(float* dst, const float* src0, const float* src1, float frac, float gain) { +static void interpolate_SSE(const float* src0, const float* src1, float* dst, float frac, float gain) { __m128 f0 = _mm_set1_ps(gain * (1.0f - frac)); __m128 f1 = _mm_set1_ps(gain * frac); @@ -465,8 +465,8 @@ static void crossfade_4x2(float* src, float* dst, const float* win, int numFrame crossfade_4x2_SSE(src, dst, win, numFrames); } -static void interpolate(float* dst, const float* src0, const float* src1, float frac, float gain) { - interpolate_SSE(dst, src0, src1, frac, gain); +static void interpolate(const float* src0, const float* src1, float* dst, float frac, float gain) { + interpolate_SSE(src0, src1, dst, frac, gain); } #else // portable reference code @@ -731,7 +731,7 @@ static void crossfade_4x2(float* src, float* dst, const float* win, int numFrame } // linear interpolation with gain -static void interpolate(float* dst, const float* src0, const float* src1, float frac, float gain) { +static void interpolate(const float* src0, const float* src1, float* dst, float frac, float gain) { float f0 = gain * (1.0f - frac); float f1 = gain * frac; @@ -983,8 +983,8 @@ static void setFilters(float firCoef[4][HRTF_TAPS], float bqCoef[5][8], int dela azimuthToIndex(azimuth, az0, az1, frac); // interpolate FIR - interpolate(firCoef[channel+0], ir_table_table[index][azL0][0], ir_table_table[index][azL1][0], fracL, gain * gainL); - interpolate(firCoef[channel+1], ir_table_table[index][azR0][1], ir_table_table[index][azR1][1], fracR, gain * gainR); + interpolate(ir_table_table[index][azL0][0], ir_table_table[index][azL1][0], firCoef[channel+0], fracL, gain * gainL); + interpolate(ir_table_table[index][azR0][1], ir_table_table[index][azR1][1], firCoef[channel+1], fracR, gain * gainR); // interpolate ITD float itd = (1.0f - frac) * itd_table_table[index][az0] + frac * itd_table_table[index][az1]; From 3e17556cc1c14c7263d8f27cf440476c7be22451 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Wed, 29 Aug 2018 10:47:02 -0700 Subject: [PATCH 145/545] Prefer static_assert() over assert() --- libraries/audio/src/AudioHRTF.cpp | 6 +++--- libraries/audio/src/avx2/AudioHRTF_avx2.cpp | 2 +- libraries/audio/src/avx512/AudioHRTF_avx512.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libraries/audio/src/AudioHRTF.cpp b/libraries/audio/src/AudioHRTF.cpp index 20d782a414..7895a70595 100644 --- a/libraries/audio/src/AudioHRTF.cpp +++ b/libraries/audio/src/AudioHRTF.cpp @@ -240,7 +240,7 @@ static void FIR_1x4_SSE(float* src, float* dst0, float* dst1, float* dst2, float float* ps = &src[i - HRTF_TAPS + 1]; // process forwards - assert(HRTF_TAPS % 4 == 0); + static_assert(HRTF_TAPS % 4 == 0, "HRTF_TAPS must be a multiple of 4"); for (int k = 0; k < HRTF_TAPS; k += 4) { @@ -425,7 +425,7 @@ static void interpolate_SSE(const float* src0, const float* src1, float* dst, fl __m128 f0 = _mm_set1_ps(gain * (1.0f - frac)); __m128 f1 = _mm_set1_ps(gain * frac); - assert(HRTF_TAPS % 4 == 0); + static_assert(HRTF_TAPS % 4 == 0, "HRTF_TAPS must be a multiple of 4"); for (int k = 0; k < HRTF_TAPS; k += 4) { @@ -505,7 +505,7 @@ static void FIR_1x4(float* src, float* dst0, float* dst1, float* dst2, float* ds float* ps = &src[i - HRTF_TAPS + 1]; // process forwards - assert(HRTF_TAPS % 4 == 0); + static_assert(HRTF_TAPS % 4 == 0, "HRTF_TAPS must be a multiple of 4"); for (int k = 0; k < HRTF_TAPS; k += 4) { diff --git a/libraries/audio/src/avx2/AudioHRTF_avx2.cpp b/libraries/audio/src/avx2/AudioHRTF_avx2.cpp index e89128b173..501f010236 100644 --- a/libraries/audio/src/avx2/AudioHRTF_avx2.cpp +++ b/libraries/audio/src/avx2/AudioHRTF_avx2.cpp @@ -44,7 +44,7 @@ void FIR_1x4_AVX2(float* src, float* dst0, float* dst1, float* dst2, float* dst3 float* ps = &src[i - HRTF_TAPS + 1]; // process forwards - assert(HRTF_TAPS % 4 == 0); + static_assert(HRTF_TAPS % 4 == 0, "HRTF_TAPS must be a multiple of 4"); for (int k = 0; k < HRTF_TAPS; k += 4) { diff --git a/libraries/audio/src/avx512/AudioHRTF_avx512.cpp b/libraries/audio/src/avx512/AudioHRTF_avx512.cpp index a8bb62be35..fcec81fa4c 100644 --- a/libraries/audio/src/avx512/AudioHRTF_avx512.cpp +++ b/libraries/audio/src/avx512/AudioHRTF_avx512.cpp @@ -44,7 +44,7 @@ void FIR_1x4_AVX512(float* src, float* dst0, float* dst1, float* dst2, float* ds float* ps = &src[i - HRTF_TAPS + 1]; // process forwards - assert(HRTF_TAPS % 4 == 0); + static_assert(HRTF_TAPS % 4 == 0, "HRTF_TAPS must be a multiple of 4"); for (int k = 0; k < HRTF_TAPS; k += 4) { From 9711076daea27342310275d1cffd3f6e193030a5 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 29 Aug 2018 10:49:29 -0700 Subject: [PATCH 146/545] Use a queued signal for pending datagrams --- libraries/networking/src/udt/Socket.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/udt/Socket.cpp b/libraries/networking/src/udt/Socket.cpp index 56b7521d7a..d764b9e8b2 100644 --- a/libraries/networking/src/udt/Socket.cpp +++ b/libraries/networking/src/udt/Socket.cpp @@ -37,7 +37,7 @@ Socket::Socket(QObject* parent, bool shouldChangeSocketOptions) : _shouldChangeSocketOptions(shouldChangeSocketOptions) { connect(&_udpSocket, &QUdpSocket::readyRead, this, &Socket::readPendingDatagrams); - connect(this, &Socket::pendingDatagrams, this, &Socket::processPendingDatagrams); + connect(this, &Socket::pendingDatagrams, this, &Socket::processPendingDatagrams, Qt::QueuedConnection); // make sure we hear about errors and state changes from the underlying socket connect(&_udpSocket, SIGNAL(error(QAbstractSocket::SocketError)), From f9d14e135149d977640f09308ec791cf6fb52b28 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 29 Aug 2018 11:17:11 -0700 Subject: [PATCH 147/545] filter time-cost drivers for region regulation --- interface/src/Application.cpp | 14 +++-- libraries/shared/src/NumericalConstants.h | 1 + libraries/workload/src/workload/Space.h | 3 +- libraries/workload/src/workload/ViewTask.cpp | 56 +++++++++++++++----- libraries/workload/src/workload/ViewTask.h | 29 ++++++---- 5 files changed, 73 insertions(+), 30 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 44bba6250b..0c25fd59a9 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5795,15 +5795,13 @@ void Application::update(float deltaTime) { auto t5 = std::chrono::high_resolution_clock::now(); workload::Timings timings(6); - timings[0] = (t4 - t0); - timings[1] = (t5 - t4); - timings[2] = (t4 - t3); - timings[3] = (t3 - t2); - timings[4] = (t2 - t1); - timings[5] = (t1 - t0); - + timings[0] = t1 - t0; // prePhysics entities + timings[1] = t2 - t1; // prePhysics avatars + timings[2] = t3 - t2; // stepPhysics + timings[3] = t4 - t3; // postPhysics + timings[4] = t5 - t4; // non-physical kinematics + timings[5] = workload::Timing_ns((int32_t)(NSECS_PER_SECOND * deltaTime)); // game loop duration _gameWorkload.updateSimulationTimings(timings); - } } } else { diff --git a/libraries/shared/src/NumericalConstants.h b/libraries/shared/src/NumericalConstants.h index 4c24a73226..8377c48960 100644 --- a/libraries/shared/src/NumericalConstants.h +++ b/libraries/shared/src/NumericalConstants.h @@ -36,6 +36,7 @@ const float METERS_PER_MILLIMETER = 0.001f; const float MILLIMETERS_PER_METER = 1000.0f; const quint64 NSECS_PER_USEC = 1000; const quint64 NSECS_PER_MSEC = 1000000; +const quint64 NSECS_PER_SECOND = 1e9; const quint64 USECS_PER_MSEC = 1000; const quint64 MSECS_PER_SECOND = 1000; const quint64 USECS_PER_SECOND = USECS_PER_MSEC * MSECS_PER_SECOND; diff --git a/libraries/workload/src/workload/Space.h b/libraries/workload/src/workload/Space.h index 310955f4c6..7dcb2217f7 100644 --- a/libraries/workload/src/workload/Space.h +++ b/libraries/workload/src/workload/Space.h @@ -70,7 +70,8 @@ private: using SpacePointer = std::shared_ptr; using Changes = std::vector; using IndexVectors = std::vector; -using Timings = std::vector; +using Timing_ns = std::chrono::nanoseconds; +using Timings = std::vector; } // namespace workload diff --git a/libraries/workload/src/workload/ViewTask.cpp b/libraries/workload/src/workload/ViewTask.cpp index 5d9953cdf4..b05a4c0c5f 100644 --- a/libraries/workload/src/workload/ViewTask.cpp +++ b/libraries/workload/src/workload/ViewTask.cpp @@ -102,9 +102,16 @@ void ControlViews::run(const workload::WorkloadContextPointer& runContext, const // Export the ranges and timings for debuging if (inTimings.size()) { - _dataExport.timings[workload::Region::R1] = std::chrono::duration(inTimings[0]).count(); + // NOTE for reference: + // inTimings[0] = prePhysics entities + // inTimings[1] = prePhysics avatars + // inTimings[2] = stepPhysics + // inTimings[3] = postPhysics + // inTimings[4] = non-physical kinematics + // inTimings[5] = game loop + _dataExport.timings[workload::Region::R1] = std::chrono::duration(inTimings[2] + inTimings[3]).count(); _dataExport.timings[workload::Region::R2] = _dataExport.timings[workload::Region::R1]; - _dataExport.timings[workload::Region::R3] = std::chrono::duration(inTimings[1]).count(); + _dataExport.timings[workload::Region::R3] = std::chrono::duration(inTimings[4]).count(); doExport = true; } @@ -115,11 +122,29 @@ void ControlViews::run(const workload::WorkloadContextPointer& runContext, const } } -glm::vec2 Regulator::run(const Timing_ns& regulationDuration, const Timing_ns& measured, const glm::vec2& current) { - // Regulate next value based on current moving toward the goal budget - float error_ms = std::chrono::duration(_budget - measured).count(); - float coef = glm::clamp(error_ms / std::chrono::duration(regulationDuration).count(), -1.0f, 1.0f); - return current * (1.0f + coef * (error_ms < 0.0f ? _relativeStepDown : _relativeStepUp)); +glm::vec2 Regulator::run(const Timing_ns& deltaTime, const Timing_ns& measuredTime, const glm::vec2& currentFrontBack) { + // measure signal: average and noise + const float FILTER_TIMESCALE = 0.5f * (float)NSECS_PER_SECOND; + float del = deltaTime.count() / FILTER_TIMESCALE; + if (del > 1.0f) { + del = 1.0f; // clamp for stability + } + _measuredTimeAverage = (1.0f - del) * _measuredTimeAverage + del * measuredTime.count(); + float diff = measuredTime.count() - _measuredTimeAverage; + _measuredTimeNoiseSquared = (1.0f - del) * _measuredTimeNoiseSquared + del * diff * diff; + float noise = sqrtf(_measuredTimeNoiseSquared); + + // check budget + float budgetDelta = _budget.count() - _measuredTimeAverage; + if (abs(budgetDelta) < noise) { + // budget is within the noise + return currentFrontBack; + } + + // clamp the step factor + del = budgetDelta < 0.0f ? -_relativeStepDown: _relativeStepUp; + + return currentFrontBack * (1.0f + del); } glm::vec2 Regulator::clamp(const glm::vec2& backFront) const { @@ -128,17 +153,24 @@ glm::vec2 Regulator::clamp(const glm::vec2& backFront) const { } void ControlViews::regulateViews(workload::Views& outViews, const workload::Timings& timings) { - for (auto& outView : outViews) { for (int32_t r = 0; r < workload::Region::NUM_VIEW_REGIONS; r++) { outView.regionBackFronts[r] = regionBackFronts[r]; } } - auto loopDuration = std::chrono::nanoseconds{ std::chrono::milliseconds(16) }; - regionBackFronts[workload::Region::R1] = regionRegulators[workload::Region::R1].run(loopDuration, timings[0], regionBackFronts[workload::Region::R1]); - regionBackFronts[workload::Region::R2] = regionRegulators[workload::Region::R2].run(loopDuration, timings[0], regionBackFronts[workload::Region::R2]); - regionBackFronts[workload::Region::R3] = regionRegulators[workload::Region::R3].run(loopDuration, timings[1], regionBackFronts[workload::Region::R3]); + // Note: for reference: + // timings[0] = prePhysics entities + // timings[1] = prePhysics avatars + // timings[2] = stepPhysics + // timings[3] = postPhysics + // timings[4] = non-physical kinematics + // timings[5] = game loop + + auto loopDuration = timings[5]; + regionBackFronts[workload::Region::R1] = regionRegulators[workload::Region::R1].run(loopDuration, timings[2] + timings[3], regionBackFronts[workload::Region::R1]); + regionBackFronts[workload::Region::R2] = regionRegulators[workload::Region::R2].run(loopDuration, timings[2] + timings[3], regionBackFronts[workload::Region::R2]); + regionBackFronts[workload::Region::R3] = regionRegulators[workload::Region::R3].run(loopDuration, timings[4], regionBackFronts[workload::Region::R3]); enforceRegionContainment(); for (auto& outView : outViews) { diff --git a/libraries/workload/src/workload/ViewTask.h b/libraries/workload/src/workload/ViewTask.h index 4fdd7e0f4c..7c1e4944f5 100644 --- a/libraries/workload/src/workload/ViewTask.h +++ b/libraries/workload/src/workload/ViewTask.h @@ -37,8 +37,8 @@ namespace workload { { 250.0f, 16000.0f } }; - const float RELATIVE_STEP_DOWN = 0.05f; - const float RELATIVE_STEP_UP = 0.04f; + const float RELATIVE_STEP_DOWN = 0.11f; + const float RELATIVE_STEP_UP = 0.09f; class SetupViewsConfig : public Job::Config{ Q_OBJECT @@ -212,20 +212,31 @@ namespace workload { }; struct Regulator { - using Timing_ns = std::chrono::nanoseconds; - Timing_ns _budget{ std::chrono::milliseconds(2) }; glm::vec2 _minRange{ MIN_VIEW_BACK_FRONTS[0] }; glm::vec2 _maxRange{ MAX_VIEW_BACK_FRONTS[0] }; - glm::vec2 _relativeStepDown{ RELATIVE_STEP_DOWN }; glm::vec2 _relativeStepUp{ RELATIVE_STEP_UP }; - + Timing_ns _budget{ std::chrono::milliseconds(2) }; + float _measuredTimeAverage { 0.0f }; + float _measuredTimeNoiseSquared { 0.0f }; Regulator() {} - Regulator(const Timing_ns& budget_ns, const glm::vec2& minRange, const glm::vec2& maxRange, const glm::vec2& relativeStepDown, const glm::vec2& relativeStepUp) : - _budget(budget_ns), _minRange(minRange), _maxRange(maxRange), _relativeStepDown(relativeStepDown), _relativeStepUp(relativeStepUp) {} + Regulator(const Timing_ns& budget_ns, + const glm::vec2& minRange, + const glm::vec2& maxRange, + const glm::vec2& relativeStepDown, + const glm::vec2& relativeStepUp) : + _minRange(minRange), + _maxRange(maxRange), + _relativeStepDown(relativeStepDown), + _relativeStepUp(relativeStepUp), + _budget(budget_ns), + _measuredTimeAverage(budget_ns.count()), + _measuredTimeNoiseSquared(0.0f) + {} - glm::vec2 run(const Timing_ns& regulationDuration, const Timing_ns& measured, const glm::vec2& current); + void setBudget(const Timing_ns& budget) { _budget = budget; } + glm::vec2 run(const Timing_ns& deltaTime, const Timing_ns& measuredTime, const glm::vec2& currentFrontBack); glm::vec2 clamp(const glm::vec2& backFront) const; }; From a134357489173f6c34d9d1a9ee51faf9ba30a0c8 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 29 Aug 2018 11:37:19 -0700 Subject: [PATCH 148/545] fix compile typo --- libraries/workload/src/workload/ViewTask.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/workload/src/workload/ViewTask.cpp b/libraries/workload/src/workload/ViewTask.cpp index b05a4c0c5f..27b136d64e 100644 --- a/libraries/workload/src/workload/ViewTask.cpp +++ b/libraries/workload/src/workload/ViewTask.cpp @@ -142,9 +142,9 @@ glm::vec2 Regulator::run(const Timing_ns& deltaTime, const Timing_ns& measuredTi } // clamp the step factor - del = budgetDelta < 0.0f ? -_relativeStepDown: _relativeStepUp; + glm::vec2 stepDelta = budgetDelta < 0.0f ? -_relativeStepDown : _relativeStepUp; - return currentFrontBack * (1.0f + del); + return currentFrontBack * (1.0f + stepDelta); } glm::vec2 Regulator::clamp(const glm::vec2& backFront) const { From dcf2074d7eb85bb35b60f89dbf97737f92b798cd Mon Sep 17 00:00:00 2001 From: David Back Date: Wed, 29 Aug 2018 11:56:37 -0700 Subject: [PATCH 149/545] remove [ camera key, allow F to enter camera without selection --- .../src/input-plugins/KeyboardMouseDevice.cpp | 2 -- scripts/system/edit.js | 13 ++----------- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp index 539546dd96..ddd51e9b9b 100755 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp @@ -304,8 +304,6 @@ controller::Input::NamedVector KeyboardMouseDevice::InputDevice::getAvailableInp availableInputs.append(Input::NamedPair(makeInput(Qt::Key_Control), "Control")); availableInputs.append(Input::NamedPair(makeInput(Qt::Key_Delete), "Delete")); availableInputs.append(Input::NamedPair(makeInput(Qt::Key_Backspace), QKeySequence(Qt::Key_Backspace).toString())); - availableInputs.append(Input::NamedPair(makeInput(Qt::Key_BracketLeft), "BracketLeft")); - availableInputs.append(Input::NamedPair(makeInput(Qt::Key_BracketRight), "BracketRight")); availableInputs.append(Input::NamedPair(makeInput(Qt::LeftButton), "LeftMouseButton")); availableInputs.append(Input::NamedPair(makeInput(Qt::MiddleButton), "MiddleMouseButton")); diff --git a/scripts/system/edit.js b/scripts/system/edit.js index dd53e8c395..b086b5624c 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -1890,18 +1890,10 @@ function toggleKey(value) { } } function focusKey(value) { - if (value === 0) { // on release - if (selectionManager.hasSelection()) { - cameraManager.enable(); - cameraManager.focus(selectionManager.worldPosition, - selectionManager.worldDimensions, - Menu.isOptionChecked(MENU_EASE_ON_FOCUS)); - } - } -} -function cameraKey(value) { if (value === 0) { // on release cameraManager.enable(); + cameraManager.focus(selectionManager.worldPosition, selectionManager.worldDimensions, + Menu.isOptionChecked(MENU_EASE_ON_FOCUS)); } } function gridKey(value) { @@ -1917,7 +1909,6 @@ mapping.from([Controller.Hardware.Keyboard.Backspace]).when([Controller.Hardware mapping.from([Controller.Hardware.Keyboard.D]).when([Controller.Hardware.Keyboard.Control]).to(deselectKey); mapping.from([Controller.Hardware.Keyboard.T]).to(toggleKey); mapping.from([Controller.Hardware.Keyboard.F]).to(focusKey); -mapping.from([Controller.Hardware.Keyboard.BracketLeft]).to(cameraKey); mapping.from([Controller.Hardware.Keyboard.G]).to(gridKey); function recursiveAdd(newParentID, parentData) { From 0e53fa3f8b8a2edb850652e8b461b967a7669fd2 Mon Sep 17 00:00:00 2001 From: David Back Date: Wed, 29 Aug 2018 12:05:46 -0700 Subject: [PATCH 150/545] only focus with selection --- scripts/system/edit.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/system/edit.js b/scripts/system/edit.js index b086b5624c..e340c75a8b 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -1892,8 +1892,10 @@ function toggleKey(value) { function focusKey(value) { if (value === 0) { // on release cameraManager.enable(); - cameraManager.focus(selectionManager.worldPosition, selectionManager.worldDimensions, - Menu.isOptionChecked(MENU_EASE_ON_FOCUS)); + if (selectionManager.hasSelection()) { + cameraManager.focus(selectionManager.worldPosition, selectionManager.worldDimensions, + Menu.isOptionChecked(MENU_EASE_ON_FOCUS)); + } } } function gridKey(value) { From f7d0cdda025964ae4d8680d2fdbdc0870c97e4bc Mon Sep 17 00:00:00 2001 From: Angus Antley Date: Wed, 29 Aug 2018 20:44:21 +0100 Subject: [PATCH 151/545] added a check for whether the head to shoulder azimuth is greater than 100 degrees. If so unflip the chest azimuth --- interface/src/avatar/MyAvatar.cpp | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 75becd2c6d..78affe2052 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -819,12 +819,13 @@ void MyAvatar::updateFromHMDSensorMatrix(const glm::mat4& hmdSensorMatrix) { // Find the vector halfway between the hip to hand azimuth vectors // This midpoint hand azimuth is in Avatar space glm::vec2 MyAvatar::computeHandAzimuth() const { - auto leftHandPoseAvatarSpace = getLeftHandPose(); - auto rightHandPoseAvatarSpace = getRightHandPose(); + controller::Pose leftHandPoseAvatarSpace = getLeftHandPose(); + controller::Pose rightHandPoseAvatarSpace = getRightHandPose(); + controller::Pose headPoseAvatarSpace = getControllerPoseInAvatarFrame(controller::Action::HEAD); const float HALFWAY = 0.50f; glm::vec2 latestHipToHandController = _hipToHandController; - if (leftHandPoseAvatarSpace.isValid() && rightHandPoseAvatarSpace.isValid()) { + if (leftHandPoseAvatarSpace.isValid() && rightHandPoseAvatarSpace.isValid() && headPoseAvatarSpace.isValid()) { // we need the old azimuth reading to prevent flipping the facing direction 180 // in the case where the hands go from being slightly less than 180 apart to slightly more than 180 apart. glm::vec2 oldAzimuthReading = _hipToHandController; @@ -833,11 +834,23 @@ glm::vec2 MyAvatar::computeHandAzimuth() const { } else { latestHipToHandController = glm::vec2(0.0f, -1.0f); } + + glm::vec3 headLookAtAvatarSpace = transformVectorFast(headPoseAvatarSpace.getMatrix(), glm::vec3(0.0f, 0.0f, 1.0f)); + glm::vec2 headAzimuthAvatarSpace = glm::vec2(headLookAtAvatarSpace.x, headLookAtAvatarSpace.z); + if (glm::length(headAzimuthAvatarSpace) > 0.0f) { + headAzimuthAvatarSpace = glm::normalize(headAzimuthAvatarSpace); + } else { + headAzimuthAvatarSpace = -latestHipToHandController; + } + // check the angular distance from forward and back float cosForwardAngle = glm::dot(latestHipToHandController, oldAzimuthReading); + float cosHeadShoulder = glm::dot(-latestHipToHandController, headAzimuthAvatarSpace); // if we are now closer to the 180 flip of the previous chest forward // then we negate our computed latestHipToHandController to keep the chest from flipping. - if (cosForwardAngle < 0.0f) { + // also check the head to shoulder azimuth difference if we negate. + // don't negate the chest azimuth if this is greater than 100 degrees. + if ((cosForwardAngle < 0.0f) && !(cosHeadShoulder < -0.2f)) { latestHipToHandController = -latestHipToHandController; } } From 6cc31e7397c8de9361f44febc3aa91278f4730d2 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Wed, 29 Aug 2018 13:30:13 -0700 Subject: [PATCH 152/545] AVX2 implementation of biquad2_4x4() --- libraries/audio/src/AudioHRTF.cpp | 6 ++- libraries/audio/src/avx2/AudioHRTF_avx2.cpp | 45 +++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/libraries/audio/src/AudioHRTF.cpp b/libraries/audio/src/AudioHRTF.cpp index 7895a70595..0f87df2346 100644 --- a/libraries/audio/src/AudioHRTF.cpp +++ b/libraries/audio/src/AudioHRTF.cpp @@ -457,8 +457,12 @@ static void interleave_4x4(float* src0, float* src1, float* src2, float* src3, f interleave_4x4_SSE(src0, src1, src2, src3, dst, numFrames); } +void biquad2_4x4_AVX2(float* src, float* dst, float coef[5][8], float state[3][8], int numFrames); + static void biquad2_4x4(float* src, float* dst, float coef[5][8], float state[3][8], int numFrames) { - biquad2_4x4_SSE(src, dst, coef, state, numFrames); + + static auto f = cpuSupportsAVX2() ? biquad2_4x4_AVX2 : biquad2_4x4_SSE; + (*f)(src, dst, coef, state, numFrames); // dispatch } static void crossfade_4x2(float* src, float* dst, const float* win, int numFrames) { diff --git a/libraries/audio/src/avx2/AudioHRTF_avx2.cpp b/libraries/audio/src/avx2/AudioHRTF_avx2.cpp index 501f010236..0c3c6b5096 100644 --- a/libraries/audio/src/avx2/AudioHRTF_avx2.cpp +++ b/libraries/audio/src/avx2/AudioHRTF_avx2.cpp @@ -87,4 +87,49 @@ void FIR_1x4_AVX2(float* src, float* dst0, float* dst1, float* dst2, float* dst3 _mm256_zeroupper(); } +// process 2 cascaded biquads on 4 channels (interleaved) +// biquads are computed in parallel, by adding one sample of delay +void biquad2_4x4_AVX2(float* src, float* dst, float coef[5][8], float state[3][8], int numFrames) { + + // enable flush-to-zero mode to prevent denormals + unsigned int ftz = _MM_GET_FLUSH_ZERO_MODE(); + _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); + + // restore state + __m256 x0 = _mm256_setzero_ps(); + __m256 y0 = _mm256_loadu_ps(state[0]); + __m256 w1 = _mm256_loadu_ps(state[1]); + __m256 w2 = _mm256_loadu_ps(state[2]); + + // biquad coefs + __m256 b0 = _mm256_loadu_ps(coef[0]); + __m256 b1 = _mm256_loadu_ps(coef[1]); + __m256 b2 = _mm256_loadu_ps(coef[2]); + __m256 a1 = _mm256_loadu_ps(coef[3]); + __m256 a2 = _mm256_loadu_ps(coef[4]); + + for (int i = 0; i < numFrames; i++) { + + // x0 = (first biquad output << 128) | input + x0 = _mm256_insertf128_ps(_mm256_permute2f128_ps(y0, y0, 0x01), _mm_loadu_ps(&src[4*i]), 0); + + // transposed Direct Form II + y0 = _mm256_fmadd_ps(x0, b0, w1); + w1 = _mm256_fmadd_ps(x0, b1, w2); + w2 = _mm256_mul_ps(x0, b2); + w1 = _mm256_fnmadd_ps(y0, a1, w1); + w2 = _mm256_fnmadd_ps(y0, a2, w2); + + _mm_storeu_ps(&dst[4*i], _mm256_extractf128_ps(y0, 1)); // second biquad output + } + + // save state + _mm256_storeu_ps(state[0], y0); + _mm256_storeu_ps(state[1], w1); + _mm256_storeu_ps(state[2], w2); + + _MM_SET_FLUSH_ZERO_MODE(ftz); + _mm256_zeroupper(); +} + #endif From cda8b82ead7a74b411e4219905f5ca29e8a0f8e3 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 29 Aug 2018 13:32:53 -0700 Subject: [PATCH 153/545] improve pointer performance --- interface/src/raypick/PathPointer.cpp | 77 ++++++++++++++----------- interface/src/raypick/PathPointer.h | 4 ++ interface/src/raypick/StylusPointer.cpp | 6 +- interface/src/raypick/StylusPointer.h | 2 + 4 files changed, 54 insertions(+), 35 deletions(-) diff --git a/interface/src/raypick/PathPointer.cpp b/interface/src/raypick/PathPointer.cpp index d434c667de..0301136bfa 100644 --- a/interface/src/raypick/PathPointer.cpp +++ b/interface/src/raypick/PathPointer.cpp @@ -54,11 +54,13 @@ PathPointer::~PathPointer() { void PathPointer::setRenderState(const std::string& state) { withWriteLock([&] { if (!_currentRenderState.empty() && state != _currentRenderState) { - if (_renderStates.find(_currentRenderState) != _renderStates.end()) { - _renderStates[_currentRenderState]->disable(); + auto renderState = _renderStates.find(_currentRenderState); + if (renderState != _renderStates.end()) { + renderState->second->disable(); } - if (_defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) { - _defaultRenderStates[_currentRenderState].second->disable(); + auto defaultRenderState = _defaultRenderStates.find(_currentRenderState); + if (defaultRenderState != _defaultRenderStates.end()) { + defaultRenderState->second.second->disable(); } } _currentRenderState = state; @@ -142,52 +144,57 @@ PickResultPointer PathPointer::getVisualPickResult(const PickResultPointer& pick void PathPointer::updateVisuals(const PickResultPointer& pickResult) { IntersectionType type = getPickedObjectType(pickResult); - if (_enabled && !_currentRenderState.empty() && _renderStates.find(_currentRenderState) != _renderStates.end() && + auto renderState = _renderStates.find(_currentRenderState); + auto defaultRenderState = _defaultRenderStates.find(_currentRenderState); + if (_enabled && !_currentRenderState.empty() && renderState != _renderStates.end() && (type != IntersectionType::NONE || _pathLength > 0.0f)) { glm::vec3 origin = getPickOrigin(pickResult); glm::vec3 end = getPickEnd(pickResult, _pathLength); glm::vec3 surfaceNormal = getPickedObjectNormal(pickResult); - _renderStates[_currentRenderState]->update(origin, end, surfaceNormal, _scaleWithAvatar, _distanceScaleEnd, _centerEndY, _faceAvatar, - _followNormal, _followNormalStrength, _pathLength, pickResult); - if (_defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) { - _defaultRenderStates[_currentRenderState].second->disable(); + renderState->second->update(origin, end, surfaceNormal, _scaleWithAvatar, _distanceScaleEnd, _centerEndY, _faceAvatar, + _followNormal, _followNormalStrength, _pathLength, pickResult); + if (defaultRenderState != _defaultRenderStates.end() && defaultRenderState->second.second->isEnabled()) { + defaultRenderState->second.second->disable(); } - } else if (_enabled && !_currentRenderState.empty() && _defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) { - if (_renderStates.find(_currentRenderState) != _renderStates.end()) { - _renderStates[_currentRenderState]->disable(); + } else if (_enabled && !_currentRenderState.empty() && defaultRenderState != _defaultRenderStates.end()) { + if (renderState != _renderStates.end() && renderState->second->isEnabled()) { + renderState->second->disable(); } glm::vec3 origin = getPickOrigin(pickResult); - glm::vec3 end = getPickEnd(pickResult, _defaultRenderStates[_currentRenderState].first); - _defaultRenderStates[_currentRenderState].second->update(origin, end, Vectors::UP, _scaleWithAvatar, _distanceScaleEnd, _centerEndY, - _faceAvatar, _followNormal, _followNormalStrength, _defaultRenderStates[_currentRenderState].first, pickResult); + glm::vec3 end = getPickEnd(pickResult, defaultRenderState->second.first); + defaultRenderState->second.second->update(origin, end, Vectors::UP, _scaleWithAvatar, _distanceScaleEnd, _centerEndY, + _faceAvatar, _followNormal, _followNormalStrength, defaultRenderState->second.first, pickResult); } else if (!_currentRenderState.empty()) { - if (_renderStates.find(_currentRenderState) != _renderStates.end()) { - _renderStates[_currentRenderState]->disable(); + if (renderState != _renderStates.end() && renderState->second->isEnabled()) { + renderState->second->disable(); } - if (_defaultRenderStates.find(_currentRenderState) != _defaultRenderStates.end()) { - _defaultRenderStates[_currentRenderState].second->disable(); + if (defaultRenderState != _defaultRenderStates.end() && defaultRenderState->second.second->isEnabled()) { + defaultRenderState->second.second->disable(); } } } void PathPointer::editRenderState(const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) { withWriteLock([&] { - updateRenderStateOverlay(_renderStates[state]->getStartID(), startProps); - updateRenderStateOverlay(_renderStates[state]->getEndID(), endProps); - QVariant startDim = startProps.toMap()["dimensions"]; - if (startDim.isValid()) { - _renderStates[state]->setStartDim(vec3FromVariant(startDim)); - } - QVariant endDim = endProps.toMap()["dimensions"]; - if (endDim.isValid()) { - _renderStates[state]->setEndDim(vec3FromVariant(endDim)); - } - QVariant rotation = endProps.toMap()["rotation"]; - if (rotation.isValid()) { - _renderStates[state]->setEndRot(quatFromVariant(rotation)); - } + auto renderState = _renderStates.find(state); + if (renderState != _renderStates.end()) { + updateRenderStateOverlay(renderState->second->getStartID(), startProps); + updateRenderStateOverlay(renderState->second->getEndID(), endProps); + QVariant startDim = startProps.toMap()["dimensions"]; + if (startDim.isValid()) { + renderState->second->setStartDim(vec3FromVariant(startDim)); + } + QVariant endDim = endProps.toMap()["dimensions"]; + if (endDim.isValid()) { + renderState->second->setEndDim(vec3FromVariant(endDim)); + } + QVariant rotation = endProps.toMap()["rotation"]; + if (rotation.isValid()) { + renderState->second->setEndRot(quatFromVariant(rotation)); + } - editRenderStatePath(state, pathProps); + editRenderStatePath(state, pathProps); + } }); } @@ -271,6 +278,7 @@ void StartEndRenderState::disable() { endProps.insert("ignoreRayIntersection", true); qApp->getOverlays().editOverlay(getEndID(), endProps); } + _enabled = false; } void StartEndRenderState::update(const glm::vec3& origin, const glm::vec3& end, const glm::vec3& surfaceNormal, bool scaleWithAvatar, bool distanceScaleEnd, bool centerEndY, @@ -337,6 +345,7 @@ void StartEndRenderState::update(const glm::vec3& origin, const glm::vec3& end, endProps.insert("ignoreRayIntersection", doesEndIgnoreRays()); qApp->getOverlays().editOverlay(getEndID(), endProps); } + _enabled = true; } glm::vec2 PathPointer::findPos2D(const PickedObject& pickedObject, const glm::vec3& origin) { diff --git a/interface/src/raypick/PathPointer.h b/interface/src/raypick/PathPointer.h index 44c1b7f82b..b3638d1f7d 100644 --- a/interface/src/raypick/PathPointer.h +++ b/interface/src/raypick/PathPointer.h @@ -47,6 +47,8 @@ public: virtual void update(const glm::vec3& origin, const glm::vec3& end, const glm::vec3& surfaceNormal, bool scaleWithAvatar, bool distanceScaleEnd, bool centerEndY, bool faceAvatar, bool followNormal, float followNormalStrength, float distance, const PickResultPointer& pickResult); + bool isEnabled() const { return _enabled; } + protected: OverlayID _startID; OverlayID _endID; @@ -59,6 +61,8 @@ protected: glm::quat _avgEndRot; bool _avgEndRotInitialized { false }; + + bool _enabled { true }; }; typedef std::unordered_map> RenderStateMap; diff --git a/interface/src/raypick/StylusPointer.cpp b/interface/src/raypick/StylusPointer.cpp index 8c0fb59106..c74b6d8509 100644 --- a/interface/src/raypick/StylusPointer.cpp +++ b/interface/src/raypick/StylusPointer.cpp @@ -64,7 +64,9 @@ void StylusPointer::updateVisuals(const PickResultPointer& pickResult) { return; } } - hide(); + if (_showing) { + hide(); + } } void StylusPointer::show(const StylusTip& tip) { @@ -80,6 +82,7 @@ void StylusPointer::show(const StylusTip& tip) { props["visible"] = true; qApp->getOverlays().editOverlay(_stylusOverlay, props); } + _showing = true; } void StylusPointer::hide() { @@ -88,6 +91,7 @@ void StylusPointer::hide() { props.insert("visible", false); qApp->getOverlays().editOverlay(_stylusOverlay, props); } + _showing = false; } bool StylusPointer::shouldHover(const PickResultPointer& pickResult) { diff --git a/interface/src/raypick/StylusPointer.h b/interface/src/raypick/StylusPointer.h index 950b03b7c9..b1903840b3 100644 --- a/interface/src/raypick/StylusPointer.h +++ b/interface/src/raypick/StylusPointer.h @@ -76,6 +76,8 @@ private: static glm::vec3 findIntersection(const PickedObject& pickedObject, const glm::vec3& origin, const glm::vec3& direction); static glm::vec2 findPos2D(const PickedObject& pickedObject, const glm::vec3& origin); + bool _showing { true }; + }; #endif // hifi_StylusPointer_h From ed4dbaa4c71de483334c26808053ec98d59955e5 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 29 Aug 2018 16:07:30 -0700 Subject: [PATCH 154/545] Refining the plot widget to be able to represent negative values --- interface/src/LODManager.cpp | 16 +++++- interface/src/LODManager.h | 12 +++- .../utilities/lib/plotperf/PlotPerf.qml | 56 ++++++++++++++++--- scripts/developer/utilities/render/lod.qml | 16 +++++- 4 files changed, 87 insertions(+), 13 deletions(-) diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index a32f3472ab..ce674f7295 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -72,6 +72,11 @@ void LODManager::autoAdjustLOD(float realTimeDelta) { // Note: we MUST clamp the blend to 1.0 for stability float blend = (realTimeDelta < LOD_ADJUST_RUNNING_AVG_TIMESCALE) ? realTimeDelta / LOD_ADJUST_RUNNING_AVG_TIMESCALE : 1.0f; _avgRenderTime = (1.0f - blend) * _avgRenderTime + blend * maxRenderTime; // msec + + float smoothBlend = (realTimeDelta < LOD_ADJUST_RUNNING_AVG_TIMESCALE * _pidCoefs.w) ? realTimeDelta / (LOD_ADJUST_RUNNING_AVG_TIMESCALE * _pidCoefs.w) : 1.0f; + _smoothRenderTime = (1.0f - smoothBlend) * _smoothRenderTime + smoothBlend * maxRenderTime; // msec + + // _avgRenderTime = maxRenderTime; if (!_automaticLODAdjust || _avgRenderTime == 0.0f) { // early exit @@ -82,13 +87,17 @@ void LODManager::autoAdjustLOD(float realTimeDelta) { float oldSolidAngle = getLODAngleDeg(); float targetFPS = 0.5 * (getLODDecreaseFPS() + getLODIncreaseFPS()); + // float targetFPS = (getLODDecreaseFPS()); float targetPeriod = 1.0f / targetFPS; float currentFPS = (float)MSECS_PER_SECOND / _avgRenderTime; + static uint64_t lastTime = usecTimestampNow(); + uint64_t now = usecTimestampNow(); auto dt = (float) ((now - lastTime) / double(USECS_PER_MSEC)); - if (dt < targetPeriod * _pidCoefs.w) return; + // if (dt < targetPeriod * _pidCoefs.w) return; + dt = realTimeDelta; lastTime = now; auto previous_error = _pidHistory.x; @@ -96,7 +105,12 @@ void LODManager::autoAdjustLOD(float realTimeDelta) { auto error = (targetFPS - currentFPS) / targetFPS; error = glm::clamp(error, -1.0f, 1.0f); + if (error <= 0.0f) { + // error = error * 2.0f; + } auto integral = previous_integral + error * dt; + glm::clamp(integral, -1.0f, 1.0f); + auto derivative = (error - previous_error) / dt; _pidHistory.x = error; diff --git a/interface/src/LODManager.h b/interface/src/LODManager.h index 74075f2400..167533a236 100644 --- a/interface/src/LODManager.h +++ b/interface/src/LODManager.h @@ -61,8 +61,13 @@ class LODManager : public QObject, public Dependency { Q_PROPERTY(float engineRunTime READ getEngineRunTime) Q_PROPERTY(float batchTime READ getBatchTime) Q_PROPERTY(float gpuTime READ getGPUTime) + Q_PROPERTY(float avgRenderTime READ getAverageRenderTime) Q_PROPERTY(float fps READ getMaxTheoreticalFPS) + + Q_PROPERTY(float smoothRenderTime READ getSmoothRenderTime) + Q_PROPERTY(float smoothFPS READ getSmoothFPS) + Q_PROPERTY(float lodLevel READ getLODLevel WRITE setLODLevel NOTIFY LODChanged) Q_PROPERTY(float lodDecreaseFPS READ getLODDecreaseFPS) Q_PROPERTY(float lodIncreaseFPS READ getLODIncreaseFPS) @@ -193,6 +198,10 @@ public: float getAverageRenderTime() const { return _avgRenderTime; }; float getMaxTheoreticalFPS() const { return (float)MSECS_PER_SECOND / _avgRenderTime; }; + float getSmoothRenderTime() const { return _smoothRenderTime; }; + float getSmoothFPS() const { return (float)MSECS_PER_SECOND / _smoothRenderTime; }; + + float getLODLevel() const; void setLODLevel(float level); @@ -246,13 +255,14 @@ private: float _gpuTime { 0.0f }; // msec float _avgRenderTime { 0.0f }; // msec + float _smoothRenderTime{ 0.0f }; float _desktopMaxRenderTime { DEFAULT_DESKTOP_MAX_RENDER_TIME }; float _hmdMaxRenderTime { DEFAULT_HMD_MAX_RENDER_TIME }; float _octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE; int _boundaryLevelAdjust = 0; - glm::vec4 _pidCoefs{ 4.0f, 0.0000000f, 0.f, 4.0f }; + glm::vec4 _pidCoefs{ 1.0f, 0.0000000f, 0.f, 8.0f }; glm::vec4 _pidHistory{ 0.0f }; glm::vec4 _pidOutputs{ 0.0f }; diff --git a/scripts/developer/utilities/lib/plotperf/PlotPerf.qml b/scripts/developer/utilities/lib/plotperf/PlotPerf.qml index 99ff5f712e..46056be5fd 100644 --- a/scripts/developer/utilities/lib/plotperf/PlotPerf.qml +++ b/scripts/developer/utilities/lib/plotperf/PlotPerf.qml @@ -50,6 +50,10 @@ Item { property var valueMax : 1 property var valueMin : 0 + property var displayMinAt0 : true + property var _displayMaxValue : 1 + property var _displayMinValue : 0 + property var _values property var tick : 0 @@ -72,7 +76,9 @@ Item { value: value, fromBinding: isBinding, valueMax: 1, + valueMin: 0, numSamplesConstantMax: 0, + numSamplesConstantMin: 0, valueHistory: new Array(), label: (plot["label"] !== undefined ? plot["label"] : ""), color: (plot["color"] !== undefined ? plot["color"] : "white"), @@ -129,7 +135,7 @@ Item { _values[i].valueMax = currentVal; _values[i].numSamplesConstantMax = 0 } - if (_values[i].valueMin < currentVal) { + if (_values[i].valueMin > currentVal) { _values[i].valueMin = currentVal; _values[i].numSamplesConstantMin = 0 } @@ -146,7 +152,7 @@ Item { if (currentValueMax < _values[i].valueMax) { currentValueMax = _values[i].valueMax } - if (currentValueMin < _values[i].valueMin) { + if (currentValueMin > _values[i].valueMin) { currentValueMin = _values[i].valueMin } } @@ -154,9 +160,12 @@ Item { if ((valueMax < currentValueMax) || (tick % VALUE_HISTORY_SIZE == 0)) { valueMax = currentValueMax; } - if ((valueMin < currentValueMin) || (tick % VALUE_HISTORY_SIZE == 0)) { + if ((valueMin > currentValueMin) || (tick % VALUE_HISTORY_SIZE == 0)) { valueMin = currentValueMin; } + _displayMaxValue = valueMax; + _displayMinValue = ( displayMinAt0 ? 0 : valueMin ) + mycanvas.requestPaint() } @@ -177,10 +186,10 @@ Item { } function pixelFromVal(val, valScale) { - return lineHeight + (height - lineHeight) * (1 - (0.9) * val / valueMax); + return lineHeight + (height - lineHeight) * (1 - (0.9) * (val - _displayMinValue) / (_displayMaxValue - _displayMinValue)); } function valueFromPixel(pixY) { - return ((pixY - lineHeight) / (height - lineHeight) - 1) * valueMax / (-0.9); + return _displayMinValue + (((pixY - lineHeight) / (height - lineHeight) - 1) * (_displayMaxValue - _displayMinValue) / (-0.9)); } function plotValueHistory(ctx, valHistory, color) { var widthStep= width / (valHistory.length - 1); @@ -208,8 +217,10 @@ Item { function displayTitle(ctx, text, maxVal) { ctx.fillStyle = "grey"; ctx.textAlign = "right"; - ctx.fillText(displayValue(valueFromPixel(lineHeight), root.valueUnit), width, lineHeight); + ctx.fillText("max" + displayValue(_displayMaxValue, root.valueUnit), width, pixelFromVal(_displayMaxValue)); + ctx.fillText("min" + displayValue(_displayMinValue, root.valueUnit), width, pixelFromVal(_displayMinValue)); + ctx.fillStyle = "white"; ctx.textAlign = "left"; ctx.fillText(text, 0, lineHeight); @@ -218,15 +229,39 @@ Item { ctx.fillStyle = Qt.rgba(0, 0, 0, root.backgroundOpacity); ctx.fillRect(0, 0, width, height); - ctx.strokeStyle= "grey"; + /* ctx.strokeStyle= "grey"; ctx.lineWidth="2"; ctx.beginPath(); ctx.moveTo(0, lineHeight + 1); - ctx.lineTo(width, lineHeight + 1); + ctx.lineTo(width, lineHeight + 1); ctx.moveTo(0, height); ctx.lineTo(width, height); + ctx.stroke();*/ + } + + function displayMaxZeroMin(ctx) { + var maxY = pixelFromVal(_displayMaxValue); + + ctx.strokeStyle= "LightSlateGray"; + ctx.lineWidth="1"; + // ctx.strokeStyle= "grey"; + ctx.beginPath(); + ctx.moveTo(0, maxY); + ctx.lineTo(width, maxY); ctx.stroke(); + + if (_displayMinValue != 0) { + var zeroY = pixelFromVal(0); + var minY = pixelFromVal(_displayMinValue); + // ctx.strokeStyle= "DarkRed"; + ctx.beginPath(); + ctx.moveTo(0, zeroY); + ctx.lineTo(width, zeroY); + ctx.moveTo(0, minY); + ctx.lineTo(width, minY); + ctx.stroke(); + } } var ctx = getContext("2d"); @@ -240,7 +275,9 @@ Item { displayValueLegend(ctx, _values[i], i) } - displayTitle(ctx, title, valueMax) + displayMaxZeroMin(ctx); + + displayTitle(ctx, title, _displayMaxValue) } } @@ -250,6 +287,7 @@ Item { onClicked: { resetMax(); + resetMin(); } } } diff --git a/scripts/developer/utilities/render/lod.qml b/scripts/developer/utilities/render/lod.qml index fe284fec93..d0562e1020 100644 --- a/scripts/developer/utilities/render/lod.qml +++ b/scripts/developer/utilities/render/lod.qml @@ -99,7 +99,7 @@ Item { label: "LOD PID Ki" valueVar: LODManager["pidKi"] valueVarSetter: (function (v) { LODManager["pidKi"] = v }) - max: 0.000005 + max: 0.1 min: 0.0 integral: false numDigits: 8 @@ -165,6 +165,11 @@ Item { label: "present", color: "#FFFF00" }, + { + prop: "batchTime", + label: "batch", + color: "#00FF00" + }, { prop: "engineRunTime", label: "engineRun", @@ -192,7 +197,12 @@ Item { { prop: "fps", label: "FPS", - color: "#FFFFFF" + color: "#FFFF55" + }, + { + prop: "smoothFPS", + label: "Smooth FPS", + color: "#9999FF" }, { prop: "lodDecreaseFPS", @@ -221,6 +231,8 @@ Item { object: LODManager valueScale: 1.0 valueUnit: "deg" + valueNumDigits: 1 + displayMinAt0: false plots: [ { prop: "pidOp", From 6cdcae33496f20c6c9096648eb169e88f49ad959 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Wed, 29 Aug 2018 16:11:51 -0700 Subject: [PATCH 155/545] switching address syntax, updating redirection domain --- interface/CMakeLists.txt | 2 - .../qml/hifi/tablet/TabletAddressDialog.qml | 4 +- interface/resources/serverless/redirect.json | 1155 ++++++++++++++++- 3 files changed, 1156 insertions(+), 5 deletions(-) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index cd058add94..ded77b9013 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -341,8 +341,6 @@ else() set(INTERFACE_EXEC_DIR "$") set(RESOURCES_DEV_DIR "${INTERFACE_EXEC_DIR}/resources") - message(STATUS "${RESOURCES_DEV_DIR}") - # copy the resources files beside the executable add_custom_command(TARGET ${TARGET_NAME} POST_BUILD COMMAND "${CMAKE_COMMAND}" -E copy_if_different diff --git a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml index c9d05aea51..bec3d82c56 100644 --- a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml +++ b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml @@ -79,7 +79,7 @@ StackView { return; } location.text = targetString; - toggleOrGo(true, targetString); + toggleOrGo(targetString, true); clearAddressLineTimer.start(); } @@ -401,7 +401,7 @@ StackView { } } - function toggleOrGo(fromSuggestions, address) { + function toggleOrGo(address, fromSuggestions) { if (address !== undefined && address !== "") { addressBarDialog.loadAddress(address, fromSuggestions); clearAddressLineTimer.start(); diff --git a/interface/resources/serverless/redirect.json b/interface/resources/serverless/redirect.json index d97f44220a..9e3b29cc26 100644 --- a/interface/resources/serverless/redirect.json +++ b/interface/resources/serverless/redirect.json @@ -1 +1,1154 @@ -{"DataVersion": 0, "Entities": [{"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{9a50eca4-5c97-4e21-8cb9-5197bb09770e}", "lastEdited": 1535474935077402, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"albedoMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.9275937080383301, "x": -3.07240629196167, "y": -9.5, "z": 1.94891357421875}, "priority": 1, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.4799537658691406}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{2d90745c-2fe2-4f9c-9dcf-b715f7a9d0c0}", "lastEdited": 1535474935076550, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"albedoMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.9275937080383301, "x": -3.07240629196167, "y": -9.5, "z": 1.94891357421875}, "priority": 1, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.4799537658691406}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{dcbca0fd-e1d8-4248-b2b4-b91346224876}", "lastEdited": 1535474935077745, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"emissiveMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel_highlight.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.927593469619751, "x": -3.072406530380249, "y": -9.5, "z": 1.94891357421875}, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.479954719543457}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{3df15ffb-9614-4ec1-81a8-e278d1917748}", "lastEdited": 1535474935076889, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"emissiveMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel_highlight.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.9275937080383301, "x": -3.07240629196167, "y": -9.5, "z": 1.94891357421875}, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.4799537658691406}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{fd138f98-d436-41d2-863a-cbef6e41e1cb}", "lastEdited": 1535474935078215, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"albedoMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.9275937080383301, "x": -3.07240629196167, "y": -9.5, "z": 1.94891357421875}, "priority": 1, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.4799537658691406}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{b2a90f9e-a5ec-4faa-a6a3-bc457516f5ee}", "lastEdited": 1535474935077505, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"albedoMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.9275937080383301, "x": -3.07240629196167, "y": -9.5, "z": 1.94891357421875}, "priority": 1, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.4799537658691406}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{5c9ef440-f022-4d21-9f00-22827851b522}", "lastEdited": 1535474935077201, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"emissiveMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel_highlight.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.948914527893066, "green": 0.16741032898426056, "red": 0.9275782108306885, "x": -3.0724217891693115, "y": -9.33258967101574, "z": 1.9489145278930664}, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904473781585693, "y": 1.028862476348877, "z": -2.479969024658203}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{2fe2296a-d74d-4ee7-bf7d-c9665bc63237}", "lastEdited": 1535474935076656, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"emissiveMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel_highlight.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.9275937080383301, "x": -3.07240629196167, "y": -9.5, "z": 1.94891357421875}, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.4799537658691406}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{86f1ba10-2921-45ad-bb74-dcbe5c49bc69}", "lastEdited": 1535474935077298, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"emissiveMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel_highlight.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.9275937080383301, "x": -3.07240629196167, "y": -9.5, "z": 1.94891357421875}, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.4799537658691406}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{1023380c-13dd-445d-bb57-1e02574e5cb3}", "lastEdited": 1535474935076124, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"emissiveMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel_highlight.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.9275937080383301, "x": -3.07240629196167, "y": -9.5, "z": 1.94891357421875}, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.4799537658691406}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{d5d841b2-0cc0-4ab2-84fe-dce3d20f6b04}", "lastEdited": 1535474935077609, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"emissiveMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel_highlight.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.927593469619751, "x": -3.072406530380249, "y": -9.5, "z": 1.94891357421875}, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.479954719543457}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{02da6c73-bab0-4e7e-b8fc-a9c0500ac66e}", "lastEdited": 1535474935075994, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"albedoMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.9275937080383301, "x": -3.07240629196167, "y": -9.5, "z": 1.94891357421875}, "priority": 1, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.4799537658691406}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{f1c2110e-1429-49b2-949d-6c73718b2d65}", "lastEdited": 1535474935078059, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"albedoMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.9275937080383301, "x": -3.07240629196167, "y": -9.5, "z": 1.94891357421875}, "priority": 1, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.4799537658691406}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{1e09084f-c0d7-4bd4-a78d-290c03391579}", "lastEdited": 1535474935076234, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"emissiveMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel_highlight.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.927593469619751, "x": -3.072406530380249, "y": -9.5, "z": 1.94891357421875}, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.479954719543457}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{e8282a17-76a5-4cd8-9f0e-473f097c8ad1}", "lastEdited": 1535474935077902, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"albedoMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.9275937080383301, "x": -3.07240629196167, "y": -9.5, "z": 1.94891357421875}, "priority": 1, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.4799537658691406}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{46fbad8a-5bc0-44c8-a9ca-beb38f672d2a}", "lastEdited": 1535474935076994, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"albedoMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.9275937080383301, "x": -3.07240629196167, "y": -9.5, "z": 1.94891357421875}, "priority": 1, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.4799537658691406}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{2861b544-1c03-439a-85ad-3758ba87ca55}", "lastEdited": 1535474935076339, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"emissiveMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel_highlight.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.9275937080383301, "x": -3.07240629196167, "y": -9.5, "z": 1.94891357421875}, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.4799537658691406}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{59b7fc7f-0100-4115-a9f8-55d5b45da540}", "lastEdited": 1535474935077098, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"albedoMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.9275937080383301, "x": -3.07240629196167, "y": -9.5, "z": 1.94891357421875}, "priority": 1, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.4799537658691406}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{2888e4b0-6eb1-4468-9b95-893dcb3e99a5}", "lastEdited": 1535474935076443, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"emissiveMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel_highlight.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.9275937080383301, "x": -3.07240629196167, "y": -9.5, "z": 1.94891357421875}, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.4799537658691406}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": true, "created": "2018-08-28T16:44:23Z", "id": "{36f00cad-64b0-415f-9f70-e92cd85836d8}", "lastEdited": 1535474935076783, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "materialData": "{\"materials\":{\"albedoMap\":\"file:///C:/users/wayne/development/hifi-fork/interface/resources/images/buttonBezel.png\"}}", "materialURL": "materialData", "owningAvatarID": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "parentID": "{00000000-0000-0000-0000-000000000001}", "parentMaterialName": "2", "position": {"blue": 5.94891357421875, "green": 0, "red": 0.9275937080383301, "x": -3.07240629196167, "y": -9.5, "z": 1.94891357421875}, "priority": 1, "queryAACube": {"scale": 0.5196152329444885, "x": -5.904480457305908, "y": 0.8614521026611328, "z": -2.4799537658691406}, "type": "Material", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": false, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 14.40000057220459, "green": 14.40000057220459, "red": 14.40000057220459, "x": 14.40000057220459, "y": 14.40000057220459, "z": 14.40000057220459}, "id": "{2cefd6b6-6a00-49c3-87c8-71b9c83f96f1}", "lastEdited": 1535474935056115, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": {"blue": 2.3440732955932617, "green": 1.7684326171875, "red": 1.8812973499298096, "x": -2.1187026500701904, "y": -7.7315673828125, "z": -1.6559267044067383}, "queryAACube": {"scale": 24.9415340423584, "x": -10.589469909667969, "y": -10.7023344039917, "z": -10.126693725585938}, "rotation": {"w": 0.8697794675827026, "x": -1.52587890625e-05, "y": 0.4933699369430542, "z": -4.57763671875e-05}, "shapeType": "box", "skyboxMode": "enabled", "type": "Zone", "userData": "{\"grabbableKey\":{\"grabbable\":false}}"}, {"clientOnly": false, "color": {"blue": 0, "green": 0, "red": 0}, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 11.117486953735352, "green": 3.580313205718994, "red": 0.20000000298023224, "x": 0.20000000298023224, "y": 3.580313205718994, "z": 11.117486953735352}, "id": "{efde7819-3a7a-4984-ac3e-28bcf69c6b1e}", "lastEdited": 1535474935053285, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": {"blue": 0, "green": 1.1583251953125, "red": 4.971565246582031, "x": 0.9715652465820312, "y": -8.3416748046875, "z": -4}, "queryAACube": {"scale": 11.681488037109375, "x": -0.8691787719726562, "y": -4.6824188232421875, "z": -5.8407440185546875}, "rotation": {"w": 0.8637980222702026, "x": -4.57763671875e-05, "y": 0.5038070678710938, "z": -1.52587890625e-05}, "shape": "Cube", "type": "Box", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": false, "color": {"blue": 0, "green": 0, "red": 0}, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 11.117486953735352, "green": 3.580313205718994, "red": 0.20000000298023224, "x": 0.20000000298023224, "y": 3.580313205718994, "z": 11.117486953735352}, "id": "{fe8d6b12-3697-4fcd-9092-af5b7f49a7f5}", "lastEdited": 1535474947253763, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": {"blue": 5.268576622009277, "green": 1.1588134765625, "red": 6.100250244140625, "x": 2.100250244140625, "y": -8.3411865234375, "z": 1.2685766220092773}, "queryAACube": {"scale": 11.681488037109375, "x": 0.2595062255859375, "y": -4.6819305419921875, "z": -0.5721673965454102}, "rotation": {"w": 0.9662165641784668, "x": -4.57763671875e-05, "y": -0.2576791048049927, "z": 1.52587890625e-05}, "shape": "Cube", "type": "Box", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": false, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 0.06014331430196762, "green": 2.582186460494995, "red": 2.582186698913574, "x": 2.582186698913574, "y": 2.582186460494995, "z": 0.06014331430196762}, "id": "{c8f9b1b1-3bd7-473c-8c2a-a8644a7acdd7}", "lastEdited": 1535474935054058, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "modelURL": "http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/oopsDialog.fbx", "name": "Oops Dialog", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": {"blue": 1.45927095413208, "green": 1.6763916015625, "red": 0, "x": -4, "y": -7.8236083984375, "z": -2.54072904586792}, "queryAACube": {"scale": 3.6522583961486816, "x": -1.8261291980743408, "y": -0.14973759651184082, "z": -0.36685824394226074}, "rotation": {"w": 0.8684672117233276, "x": -4.57763671875e-05, "y": 0.4957197904586792, "z": -7.62939453125e-05}, "type": "Model", "userData": "{\"grabbableKey\":{\"grabbable\":false}}"}, {"angularDamping": 0, "clientOnly": false, "color": {"blue": 0, "green": 0, "red": 255}, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 0.20000000298023224, "green": 0.20000000298023224, "red": 0.20000000298023224, "x": 0.20000000298023224, "y": 0.20000000298023224, "z": 0.20000000298023224}, "id": "{d0b0491a-5c7d-4cd2-9ebe-492b709a702b}", "lastEdited": 1535474935052912, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "name": "Particle Rotate", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": {"blue": 3.8216662406921387, "green": 0, "red": 1.2409718036651611, "x": -2.759028196334839, "y": -9.5, "z": -0.17833375930786133}, "queryAACube": {"scale": 0.3464101552963257, "x": 1.0677666664123535, "y": -0.17320507764816284, "z": 3.648461103439331}, "rotation": {"w": 0.6444342136383057, "x": -0.08220034837722778, "y": -0.6649118661880493, "z": 0.3684900999069214}, "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", "scriptTimestamp": 1532724769253, "shape": "Cube", "type": "Box", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"angularDamping": 0, "clientOnly": false, "color": {"blue": 0, "green": 0, "red": 255}, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 0.20000000298023224, "green": 0.20000000298023224, "red": 0.20000000298023224, "x": 0.20000000298023224, "y": 0.20000000298023224, "z": 0.20000000298023224}, "id": "{ae4a84ee-4e95-4e6b-b63d-399893a9b3f9}", "lastEdited": 1535474935052114, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "name": "Particle Rotate", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": {"blue": 1.3116319179534912, "green": 0, "red": 2.705613613128662, "x": -1.294386386871338, "y": -9.5, "z": -2.688368082046509}, "queryAACube": {"scale": 0.3464101552963257, "x": 2.5324084758758545, "y": -0.17320507764816284, "z": 1.1384267807006836}, "rotation": {"w": 0.9127794504165649, "x": 0.2575265169143677, "y": 0.15553522109985352, "z": 0.2761729955673218}, "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", "scriptTimestamp": 1532724769253, "shape": "Cube", "type": "Box", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"angularDamping": 0, "clientOnly": false, "color": {"blue": 0, "green": 0, "red": 255}, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 0.20000000298023224, "green": 0.20000000298023224, "red": 0.20000000298023224, "x": 0.20000000298023224, "y": 0.20000000298023224, "z": 0.20000000298023224}, "id": "{c1404297-9c6a-4d2d-b91d-c844ddd391db}", "lastEdited": 1535474935051740, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "name": "Particle Rotate", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": {"blue": 3.8216662406921387, "green": 0.0772705078125, "red": 1.2409718036651611, "x": -2.759028196334839, "y": -9.4227294921875, "z": -0.17833375930786133}, "queryAACube": {"scale": 0.3464101552963257, "x": 1.0677666664123535, "y": -0.09593456983566284, "z": 3.648461103439331}, "rotation": {"w": 0.926024317741394, "x": 0.20308232307434082, "y": -0.010269343852996826, "z": 0.3179827928543091}, "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", "scriptTimestamp": 1532724769253, "shape": "Cube", "type": "Box", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": false, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 9.030570983886719, "green": 0.0719478651881218, "red": 9.030570983886719, "x": 9.030570983886719, "y": 0.0719478651881218, "z": 9.030570983886719}, "id": "{f17920f3-1571-4c5e-b002-e328cf202037}", "lastEdited": 1535474950564649, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "modelURL": "http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/floor.fbx", "name": "Floor", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": {"blue": 4.2324604988098145, "green": 0.17547607421875, "red": 4.802988529205322, "x": 0.8029885292053223, "y": -9.32452392578125, "z": 0.23246049880981445}, "queryAACube": {"scale": 12.771358489990234, "x": -1.582690715789795, "y": -6.210203170776367, "z": -2.1532187461853027}, "rotation": {"w": 0.8648051023483276, "x": -1.52587890625e-05, "y": 0.5020675659179688, "z": -4.57763671875e-05}, "shapeType": "simple-hull", "type": "Model", "userData": "{\"grabbableKey\":{\"grabbable\":false}}"}, {"alpha": 0, "alphaFinish": 0, "alphaStart": 0.25, "clientOnly": false, "colorFinish": {"blue": 0, "green": 0, "red": 0, "x": 0, "y": 0, "z": 0}, "colorStart": {"blue": 255, "green": 255, "red": 255, "x": 255, "y": 255, "z": 255}, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 13.24000072479248, "green": 13.24000072479248, "red": 13.24000072479248, "x": 13.24000072479248, "y": 13.24000072479248, "z": 13.24000072479248}, "emitAcceleration": {"blue": 0, "green": 0.10000000149011612, "red": 0, "x": 0, "y": 0.10000000149011612, "z": 0}, "emitDimensions": {"blue": 1, "green": 1, "red": 1, "x": 1, "y": 1, "z": 1}, "emitOrientation": {"w": 1, "x": -1.52587890625e-05, "y": -1.52587890625e-05, "z": -1.52587890625e-05}, "emitRate": 6, "emitSpeed": 0, "id": "{7561445a-4f9c-41aa-96b9-b8ce8ad686d3}", "lastEdited": 1535474935056499, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "lifespan": 10, "maxParticles": 10, "name": "Stars", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "particleRadius": 0.07000000029802322, "polarFinish": 3.1415927410125732, "position": {"blue": 1.3712034225463867, "green": 0.5220947265625, "red": 2.6281180381774902, "x": -1.3718819618225098, "y": -8.9779052734375, "z": -2.6287965774536133}, "queryAACube": {"scale": 22.932353973388672, "x": -8.838058471679688, "y": -10.944082260131836, "z": -10.09497356414795}, "radiusFinish": 0, "radiusStart": 0, "rotation": {"w": 0.9852597713470459, "x": -1.52587890625e-05, "y": -0.17106890678405762, "z": -7.62939453125e-05}, "speedSpread": 0, "spinFinish": null, "spinStart": null, "textures": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/star.png", "type": "ParticleEffect", "userData": "{\"grabbableKey\":{\"grabbable\":false}}"}, {"alpha": 0, "alphaFinish": 0, "alphaStart": 1, "clientOnly": false, "color": {"blue": 255, "green": 205, "red": 3}, "colorFinish": {"blue": 0, "green": 0, "red": 0, "x": 0, "y": 0, "z": 0}, "colorStart": {"blue": 255, "green": 204, "red": 0, "x": 0, "y": 204, "z": 255}, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 2.5, "green": 2.5, "red": 2.5, "x": 2.5, "y": 2.5, "z": 2.5}, "emitAcceleration": {"blue": 0, "green": 0, "red": 0, "x": 0, "y": 0, "z": 0}, "emitDimensions": {"blue": 1, "green": 1, "red": 1, "x": 1, "y": 1, "z": 1}, "emitOrientation": {"w": 0.9993909597396851, "x": 0.034897372126579285, "y": -1.525880907138344e-05, "z": -1.525880907138344e-05}, "emitRate": 2, "emitSpeed": 0, "emitterShouldTrail": true, "id": "{7c59b77f-2f88-4c35-899b-3e42bd486ed6}", "lastEdited": 1535474935050547, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "lifespan": 10, "maxParticles": 40, "name": "Rays", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "particleRadius": 0.75, "polarFinish": 3.1415927410125732, "position": {"blue": 3.814434051513672, "green": 1.44122314453125, "red": 1.2319090366363525, "x": -2.7680909633636475, "y": -8.05877685546875, "z": -0.18556594848632812}, "queryAACube": {"scale": 4.330127239227295, "x": -0.9331545829772949, "y": -0.7238404750823975, "z": 1.6493704319000244}, "radiusFinish": 0.10000000149011612, "radiusStart": 0, "rotation": {"w": 0.9594720602035522, "x": -1.52587890625e-05, "y": 0.28178834915161133, "z": -4.57763671875e-05}, "speedSpread": 0, "spinFinish": null, "spinStart": null, "textures": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/stripe.png", "type": "ParticleEffect", "userData": "{\"grabbableKey\":{\"grabbable\":false}}"}, {"angularDamping": 0, "clientOnly": false, "color": {"blue": 0, "green": 0, "red": 255}, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 0.20000000298023224, "green": 0.20000000298023224, "red": 0.20000000298023224, "x": 0.20000000298023224, "y": 0.20000000298023224, "z": 0.20000000298023224}, "id": "{55dd2b28-1c53-431b-b2ea-61155dfc6652}", "lastEdited": 1535474935055239, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "name": "Particle Rotate", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": {"blue": 1.3116319179534912, "green": 0.15618896484375, "red": 2.705613613128662, "x": -1.294386386871338, "y": -9.34381103515625, "z": -2.688368082046509}, "queryAACube": {"scale": 0.3464101552963257, "x": 2.5324084758758545, "y": -0.017016112804412842, "z": 1.1384267807006836}, "rotation": {"w": 0.46953535079956055, "x": -0.16719311475753784, "y": -0.7982757091522217, "z": 0.3380941152572632}, "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", "scriptTimestamp": 1532724769253, "shape": "Cube", "type": "Box", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"angularDamping": 0, "clientOnly": false, "color": {"blue": 0, "green": 0, "red": 255}, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 0.20000000298023224, "green": 0.20000000298023224, "red": 0.20000000298023224, "x": 0.20000000298023224, "y": 0.20000000298023224, "z": 0.20000000298023224}, "id": "{f40563f7-01e3-4faf-ad1b-19cab7a386a1}", "lastEdited": 1535474935054426, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "name": "Particle Rotate", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": {"blue": 1.3116319179534912, "green": 0.0772705078125, "red": 2.705613613128662, "x": -1.294386386871338, "y": -9.4227294921875, "z": -2.688368082046509}, "queryAACube": {"scale": 0.3464101552963257, "x": 2.5324084758758545, "y": -0.09593456983566284, "z": 1.1384267807006836}, "rotation": {"w": -0.38777750730514526, "x": -0.37337303161621094, "y": -0.8409399390220642, "z": 0.055222392082214355}, "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", "scriptTimestamp": 1532724769253, "shape": "Cube", "type": "Box", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"alpha": 0, "alphaFinish": 0, "alphaStart": 1, "clientOnly": false, "color": {"blue": 211, "green": 227, "red": 104}, "colorFinish": {"blue": 0, "green": 0, "red": 0, "x": 0, "y": 0, "z": 0}, "colorStart": {"blue": 211, "green": 227, "red": 104, "x": 104, "y": 227, "z": 211}, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 2.5, "green": 2.5, "red": 2.5, "x": 2.5, "y": 2.5, "z": 2.5}, "emitAcceleration": {"blue": 0, "green": 0, "red": 0, "x": 0, "y": 0, "z": 0}, "emitDimensions": {"blue": 1, "green": 1, "red": 1, "x": 1, "y": 1, "z": 1}, "emitOrientation": {"w": 0.9993909597396851, "x": 0.034897372126579285, "y": -1.525880907138344e-05, "z": -1.525880907138344e-05}, "emitRate": 2, "emitSpeed": 0, "id": "{c4a86707-2eaa-41f5-a1ad-3e6029178d75}", "lastEdited": 1535474935052538, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "lifespan": 10, "maxParticles": 40, "name": "Rays", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "particleRadius": 0.75, "polarFinish": 3.1415927410125732, "position": {"blue": 1.3553659915924072, "green": 1.44122314453125, "red": 2.572803497314453, "x": -1.4271965026855469, "y": -8.05877685546875, "z": -2.6446340084075928}, "queryAACube": {"scale": 4.330127239227295, "x": 0.40773987770080566, "y": -0.7238404750823975, "z": -0.8096976280212402}, "radiusFinish": 0.10000000149011612, "radiusStart": 0, "rotation": {"w": 0.9803768396377563, "x": -1.52587890625e-05, "y": 0.19707024097442627, "z": -7.62939453125e-05}, "speedSpread": 0, "spinFinish": null, "spinStart": null, "textures": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/stripe.png", "type": "ParticleEffect", "userData": "{\"grabbableKey\":{\"grabbable\":false}}"}, {"angularDamping": 0, "clientOnly": false, "color": {"blue": 0, "green": 0, "red": 255}, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 0.20000000298023224, "green": 0.20000000298023224, "red": 0.20000000298023224, "x": 0.20000000298023224, "y": 0.20000000298023224, "z": 0.20000000298023224}, "id": "{65dd9c7f-815d-4b50-ba3b-24709691aed1}", "lastEdited": 1535474935056805, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "name": "Particle Rotate", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": {"blue": 3.8216662406921387, "green": 0.15618896484375, "red": 1.2409718036651611, "x": -2.759028196334839, "y": -9.34381103515625, "z": -0.17833375930786133}, "queryAACube": {"scale": 0.3464101552963257, "x": 1.0677666664123535, "y": -0.017016112804412842, "z": 3.648461103439331}, "rotation": {"w": 0.6747081279754639, "x": -0.06532388925552368, "y": -0.6342412233352661, "z": 0.37175559997558594}, "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", "scriptTimestamp": 1532724769253, "shape": "Cube", "type": "Box", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": false, "color": {"blue": 0, "green": 0, "red": 0}, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 11.117486953735352, "green": 3.580313205718994, "red": 0.20000000298023224, "x": 0.20000000298023224, "y": 3.580313205718994, "z": 11.117486953735352}, "id": "{4e0f3381-ac88-48ab-9378-0b7818188234}", "lastEdited": 1535474935053657, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": {"blue": 6.1806135177612305, "green": 1.1588134765625, "red": 1.4755167961120605, "x": -2.5244832038879395, "y": -8.3411865234375, "z": 2.1806135177612305}, "queryAACube": {"scale": 11.681488037109375, "x": -4.365227222442627, "y": -4.6819305419921875, "z": 0.33986949920654297}, "rotation": {"w": 0.8637980222702026, "x": -4.57763671875e-05, "y": 0.5038070678710938, "z": -1.52587890625e-05}, "shape": "Cube", "type": "Box", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"clientOnly": false, "color": {"blue": 0, "green": 0, "red": 0}, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 11.117486953735352, "green": 3.580313205718994, "red": 0.20000000298023224, "x": 0.20000000298023224, "y": 3.580313205718994, "z": 11.117486953735352}, "id": "{2da3a1d6-c757-4cc3-b20c-d7ec87eedd52}", "lastEdited": 1535474935050931, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": {"blue": 1.9063844680786133, "green": 1.15850830078125, "red": 0.16632509231567383, "x": -3.833674907684326, "y": -8.34149169921875, "z": -2.0936155319213867}, "queryAACube": {"scale": 11.681488037109375, "x": -5.674418926239014, "y": -4.6822357177734375, "z": -3.934359550476074}, "rotation": {"w": 0.9666743278503418, "x": -4.57763671875e-05, "y": -0.2560006380081177, "z": 1.52587890625e-05}, "shape": "Cube", "type": "Box", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false}, {"alpha": 0, "alphaFinish": 0, "alphaStart": 0.25, "clientOnly": false, "colorFinish": {"blue": 0, "green": 0, "red": 0, "x": 0, "y": 0, "z": 0}, "colorStart": {"blue": 255, "green": 255, "red": 255, "x": 255, "y": 255, "z": 255}, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 13.24000072479248, "green": 13.24000072479248, "red": 13.24000072479248, "x": 13.24000072479248, "y": 13.24000072479248, "z": 13.24000072479248}, "emitAcceleration": {"blue": 0, "green": 0.10000000149011612, "red": 0, "x": 0, "y": 0.10000000149011612, "z": 0}, "emitDimensions": {"blue": 1, "green": 1, "red": 1, "x": 1, "y": 1, "z": 1}, "emitOrientation": {"w": 1, "x": -1.52587890625e-05, "y": -1.52587890625e-05, "z": -1.52587890625e-05}, "emitRate": 6, "emitSpeed": 0, "emitterShouldTrail": true, "id": "{7db57102-9a57-48d6-9937-bcec7892c3d9}", "lastEdited": 1535474935058139, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "lifespan": 10, "maxParticles": 10, "name": "Stars", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "particleRadius": 0.07000000029802322, "polarFinish": 3.1415927410125732, "position": {"blue": 3.78922963142395, "green": 0.5220947265625, "red": 1.1928560733795166, "x": -2.8071439266204834, "y": -8.9779052734375, "z": -0.2107703685760498}, "queryAACube": {"scale": 22.932353973388672, "x": -10.273321151733398, "y": -10.944082260131836, "z": -7.676947593688965}, "radiusFinish": 0, "radiusStart": 0, "rotation": {"w": 0.996429443359375, "x": -1.52587890625e-05, "y": -0.08442819118499756, "z": -4.57763671875e-05}, "speedSpread": 0, "spinFinish": null, "spinStart": null, "textures": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/star.png", "type": "ParticleEffect", "userData": "{\"grabbableKey\":{\"grabbable\":false}}"}, {"clientOnly": false, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 2.1097896099090576, "green": 0.04847164824604988, "red": 1.458284616470337, "x": 1.458284616470337, "y": 0.04847164824604988, "z": 2.1097896099090576}, "id": "{434940be-0b45-4ca2-97db-91e698c20bfd}", "lastEdited": 1535474935055655, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "modelURL": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/portal2.fbx", "name": "Back", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": {"blue": 1.5835940837860107, "green": 0.2467041015625, "red": 3.0345542430877686, "x": -0.9654457569122314, "y": -9.2532958984375, "z": -2.4164059162139893}, "queryAACube": {"scale": 2.5651814937591553, "x": 1.751963496208191, "y": -1.0358866453170776, "z": 0.3010033369064331}, "rotation": {"w": 0.9084458351135254, "x": -1.52587890625e-05, "y": 0.4179598093032837, "z": -0.0001068115234375}, "type": "Model", "userData": "{\"grabbableKey\":{\"grabbable\":true}}"}, {"clientOnly": false, "created": "2018-08-28T16:44:23Z", "dimensions": {"blue": 2.1097896099090576, "green": 0.04847164824604988, "red": 1.458284616470337, "x": 1.458284616470337, "y": 0.04847164824604988, "z": 2.1097896099090576}, "id": "{5f853b12-33b9-4f40-92a8-4506047fdcd8}", "lastEdited": 1535474935051356, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "modelURL": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/portal1.fbx", "name": "Try Again", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": {"blue": 3.946338653564453, "green": 0.2467041015625, "red": 1.6013128757476807, "x": -2.3986871242523193, "y": -9.2532958984375, "z": -0.053661346435546875}, "queryAACube": {"scale": 2.5651814937591553, "x": 0.318722128868103, "y": -1.0358866453170776, "z": 2.663747787475586}, "rotation": {"w": 0.8220492601394653, "x": -1.52587890625e-05, "y": 0.5693598985671997, "z": -0.0001068115234375}, "type": "Model", "userData": "{\"grabbableKey\":{\"grabbable\":true}}"}], "Id": "{aa6032b9-9c35-4481-acd9-03b97400b83a}", "Version": 93} \ No newline at end of file +{ + "DataVersion": 0, + "Entities": [ + { + "clientOnly": false, + "collidesWith": "static,dynamic,kinematic,otherAvatar,", + "collisionMask": 23, + "created": "2018-08-29T22:59:44Z", + "dimensions": { + "blue": 0.26190000772476196, + "green": 0.5595999956130981, + "red": 0.5318999886512756, + "x": 0.5318999886512756, + "y": 0.5595999956130981, + "z": 0.26190000772476196 + }, + "id": "{4782f05d-ca51-41d4-9d19-21b8cad5ec2d}", + "lastEdited": 1535584079688600, + "lastEditedBy": "{f5457c14-32ca-45c2-9dde-4f5b30b3be1b}", + "name": "Try Again Box", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 4.54052734375, + "green": 1.722428798675537, + "red": 4.593362331390381, + "x": 4.593362331390381, + "y": 1.722428798675537, + "z": 4.54052734375 + }, + "queryAACube": { + "scale": 0.8152676820755005, + "x": 4.185728549957275, + "y": 1.3147950172424316, + "z": 4.1328935623168945 + }, + "rotation": { + "w": 0.9868703484535217, + "x": -0.010178769007325172, + "y": -0.15702557563781738, + "z": 0.03642075136303902 + }, + "script": "file:///C:/Users/wayne/development/tryAgainBoxEntityScript.js", + "shape": "Cube", + "type": "Box", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}", + "visible": false + }, + { + "clientOnly": false, + "created": "2018-08-29T23:01:55Z", + "dimensions": { + "blue": 0.26190000772476196, + "green": 0.5595999956130981, + "red": 0.5318999886512756, + "x": 0.5318999886512756, + "y": 0.5595999956130981, + "z": 0.26190000772476196 + }, + "id": "{8c9287c8-3826-4f2e-944e-05d8d4715fb8}", + "lastEdited": 1535584095676575, + "lastEditedBy": "{f5457c14-32ca-45c2-9dde-4f5b30b3be1b}", + "name": "Back Box", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 3.9590959548950195, + "green": 1.738053798675537, + "red": 5.0181121826171875, + "x": 5.0181121826171875, + "y": 1.738053798675537, + "z": 3.9590959548950195 + }, + "queryAACube": { + "scale": 0.8152676820755005, + "x": 4.610478401184082, + "y": 1.3304200172424316, + "z": 3.551462173461914 + }, + "rotation": { + "w": 0.9366722106933594, + "x": 0, + "y": -0.3502073884010315, + "z": 0 + }, + "script": "file:///C:/Users/wayne/development/backBoxEntityScript.js", + "shape": "Cube", + "type": "Box", + "userData": "{\"grabbableKey\":{\"grabbable\":true}}", + "visible": false + }, + { + "clientOnly": false, + "created": "2018-08-29T22:57:33Z", + "dimensions": { + "blue": 14.40000057220459, + "green": 14.40000057220459, + "red": 14.40000057220459, + "x": 14.40000057220459, + "y": 14.40000057220459, + "z": 14.40000057220459 + }, + "id": "{8e6bd656-d764-4724-a89d-7b4ff96abf8a}", + "lastEdited": 1535583477860044, + "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 2.3440732955932617, + "green": 1.7684326171875, + "red": 1.8812973499298096, + "x": 1.8812973499298096, + "y": 1.7684326171875, + "z": 2.3440732955932617 + }, + "queryAACube": { + "scale": 24.9415340423584, + "x": -10.589469909667969, + "y": -10.7023344039917, + "z": -10.126693725585938 + }, + "rotation": { + "w": 0.8697794675827026, + "x": -1.52587890625e-05, + "y": 0.4933699369430542, + "z": -4.57763671875e-05 + }, + "shapeType": "box", + "skyboxMode": "enabled", + "type": "Zone", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}" + }, + { + "alpha": 0, + "alphaFinish": 0, + "alphaStart": 0.25, + "clientOnly": false, + "colorFinish": { + "blue": 0, + "green": 0, + "red": 0, + "x": 0, + "y": 0, + "z": 0 + }, + "colorStart": { + "blue": 255, + "green": 255, + "red": 255, + "x": 255, + "y": 255, + "z": 255 + }, + "created": "2018-08-29T22:57:33Z", + "dimensions": { + "blue": 13.24000072479248, + "green": 13.24000072479248, + "red": 13.24000072479248, + "x": 13.24000072479248, + "y": 13.24000072479248, + "z": 13.24000072479248 + }, + "emitAcceleration": { + "blue": 0, + "green": 0.10000000149011612, + "red": 0, + "x": 0, + "y": 0.10000000149011612, + "z": 0 + }, + "emitDimensions": { + "blue": 1, + "green": 1, + "red": 1, + "x": 1, + "y": 1, + "z": 1 + }, + "emitOrientation": { + "w": 1, + "x": -1.52587890625e-05, + "y": -1.52587890625e-05, + "z": -1.52587890625e-05 + }, + "emitRate": 6, + "emitSpeed": 0, + "id": "{b5ba3aa4-2eb9-4cfd-aec7-43635511c6b7}", + "lastEdited": 1535583477861791, + "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "lifespan": 10, + "maxParticles": 10, + "name": "Stars", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "particleRadius": 0.07000000029802322, + "polarFinish": 3.1415927410125732, + "position": { + "blue": 1.3712034225463867, + "green": 0.5220947265625, + "red": 2.6281180381774902, + "x": 2.6281180381774902, + "y": 0.5220947265625, + "z": 1.3712034225463867 + }, + "queryAACube": { + "scale": 22.932353973388672, + "x": -8.838058471679688, + "y": -10.944082260131836, + "z": -10.09497356414795 + }, + "radiusFinish": 0, + "radiusStart": 0, + "rotation": { + "w": 0.9852597713470459, + "x": -1.52587890625e-05, + "y": -0.17106890678405762, + "z": -7.62939453125e-05 + }, + "speedSpread": 0, + "spinFinish": null, + "spinStart": null, + "textures": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/star.png", + "type": "ParticleEffect", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}" + }, + { + "clientOnly": false, + "color": { + "blue": 0, + "green": 0, + "red": 0 + }, + "created": "2018-08-29T22:57:33Z", + "dimensions": { + "blue": 11.117486953735352, + "green": 3.580313205718994, + "red": 0.20000000298023224, + "x": 0.20000000298023224, + "y": 3.580313205718994, + "z": 11.117486953735352 + }, + "id": "{12a26c55-c411-4c4c-a124-cac9c80f9532}", + "lastEdited": 1535583681180522, + "lastEditedBy": "{f5457c14-32ca-45c2-9dde-4f5b30b3be1b}", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 1.9063844680786133, + "green": 1.15850830078125, + "red": 0.16632509231567383, + "x": 0.16632509231567383, + "y": 1.15850830078125, + "z": 1.9063844680786133 + }, + "queryAACube": { + "scale": 11.681488037109375, + "x": -5.674418926239014, + "y": -4.6822357177734375, + "z": -3.934359550476074 + }, + "rotation": { + "w": 0.9666743278503418, + "x": -4.57763671875e-05, + "y": -0.2560006380081177, + "z": 1.52587890625e-05 + }, + "shape": "Cube", + "type": "Box", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}", + "visible": false + }, + { + "angularDamping": 0, + "clientOnly": false, + "color": { + "blue": 0, + "green": 0, + "red": 255 + }, + "created": "2018-08-29T22:57:33Z", + "dimensions": { + "blue": 0.20000000298023224, + "green": 0.20000000298023224, + "red": 0.20000000298023224, + "x": 0.20000000298023224, + "y": 0.20000000298023224, + "z": 0.20000000298023224 + }, + "id": "{e8fd2c79-1303-49e4-8e4a-823272d6558c}", + "lastEdited": 1535583477862445, + "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "name": "Particle Rotate", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 1.3116319179534912, + "green": 0.0772705078125, + "red": 2.705613613128662, + "x": 2.705613613128662, + "y": 0.0772705078125, + "z": 1.3116319179534912 + }, + "queryAACube": { + "scale": 0.3464101552963257, + "x": 2.5324084758758545, + "y": -0.09593456983566284, + "z": 1.1384267807006836 + }, + "rotation": { + "w": -0.38777750730514526, + "x": -0.37337303161621094, + "y": -0.8409399390220642, + "z": 0.055222392082214355 + }, + "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", + "scriptTimestamp": 1532724769253, + "shape": "Cube", + "type": "Box", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}", + "visible": false + }, + { + "clientOnly": false, + "created": "2018-08-29T22:57:33Z", + "dimensions": { + "blue": 9.030570983886719, + "green": 0.0719478651881218, + "red": 9.030570983886719, + "x": 9.030570983886719, + "y": 0.0719478651881218, + "z": 9.030570983886719 + }, + "id": "{85b4551d-c05d-4038-b188-30ad5db9c23a}", + "lastEdited": 1535583477861514, + "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "modelURL": "http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/floor.fbx", + "name": "Floor", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 4.2324604988098145, + "green": 0.17547607421875, + "red": 4.802988529205322, + "x": 4.802988529205322, + "y": 0.17547607421875, + "z": 4.2324604988098145 + }, + "queryAACube": { + "scale": 12.771358489990234, + "x": -1.582690715789795, + "y": -6.210203170776367, + "z": -2.1532187461853027 + }, + "rotation": { + "w": 0.8648051023483276, + "x": -1.52587890625e-05, + "y": 0.5020675659179688, + "z": -4.57763671875e-05 + }, + "shapeType": "simple-hull", + "type": "Model", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}" + }, + { + "clientOnly": false, + "created": "2018-08-29T22:57:33Z", + "dimensions": { + "blue": 0.06014331430196762, + "green": 2.582186460494995, + "red": 2.582186698913574, + "x": 2.582186698913574, + "y": 2.582186460494995, + "z": 0.06014331430196762 + }, + "id": "{8e4d8047-c2e2-4b2c-bfa2-c732d419d59a}", + "lastEdited": 1535583477860645, + "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "modelURL": "http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/oopsDialog.fbx", + "name": "Oops Dialog", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 1.45927095413208, + "green": 1.6763916015625, + "red": 0, + "x": 0, + "y": 1.6763916015625, + "z": 1.45927095413208 + }, + "queryAACube": { + "scale": 3.6522583961486816, + "x": -1.8261291980743408, + "y": -0.14973759651184082, + "z": -0.36685824394226074 + }, + "rotation": { + "w": 0.8684672117233276, + "x": -4.57763671875e-05, + "y": 0.4957197904586792, + "z": -7.62939453125e-05 + }, + "type": "Model", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}" + }, + { + "angularDamping": 0, + "clientOnly": false, + "color": { + "blue": 0, + "green": 0, + "red": 255 + }, + "created": "2018-08-29T22:57:33Z", + "dimensions": { + "blue": 0.20000000298023224, + "green": 0.20000000298023224, + "red": 0.20000000298023224, + "x": 0.20000000298023224, + "y": 0.20000000298023224, + "z": 0.20000000298023224 + }, + "id": "{4fc1436d-00e7-43ec-83e1-f70cff544885}", + "lastEdited": 1535583477862827, + "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "name": "Particle Rotate", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 3.8216662406921387, + "green": 0.15618896484375, + "red": 1.2409718036651611, + "x": 1.2409718036651611, + "y": 0.15618896484375, + "z": 3.8216662406921387 + }, + "queryAACube": { + "scale": 0.3464101552963257, + "x": 1.0677666664123535, + "y": -0.017016112804412842, + "z": 3.648461103439331 + }, + "rotation": { + "w": 0.6747081279754639, + "x": -0.06532388925552368, + "y": -0.6342412233352661, + "z": 0.37175559997558594 + }, + "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", + "scriptTimestamp": 1532724769253, + "shape": "Cube", + "type": "Box", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}", + "visible": false + }, + { + "clientOnly": false, + "color": { + "blue": 0, + "green": 0, + "red": 0 + }, + "created": "2018-08-29T22:57:33Z", + "dimensions": { + "blue": 11.117486953735352, + "green": 3.580313205718994, + "red": 0.20000000298023224, + "x": 0.20000000298023224, + "y": 3.580313205718994, + "z": 11.117486953735352 + }, + "id": "{81a7c620-88ea-4056-b148-449d963c7eb5}", + "lastEdited": 1535583477860260, + "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 0, + "green": 1.1583251953125, + "red": 4.971565246582031, + "x": 4.971565246582031, + "y": 1.1583251953125, + "z": 0 + }, + "queryAACube": { + "scale": 11.681488037109375, + "x": -0.8691787719726562, + "y": -4.6824188232421875, + "z": -5.8407440185546875 + }, + "rotation": { + "w": 0.8637980222702026, + "x": -4.57763671875e-05, + "y": 0.5038070678710938, + "z": -1.52587890625e-05 + }, + "shape": "Cube", + "type": "Box", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}", + "visible": false + }, + { + "clientOnly": false, + "created": "2018-08-29T22:57:33Z", + "dimensions": { + "blue": 2.1097896099090576, + "green": 0.04847164824604988, + "red": 1.458284616470337, + "x": 1.458284616470337, + "y": 0.04847164824604988, + "z": 2.1097896099090576 + }, + "id": "{09436993-6042-49ff-bfec-0fd28f792251}", + "lastEdited": 1535583477863518, + "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "modelURL": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/portal1.fbx", + "name": "Try Again", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 3.946338653564453, + "green": 0.2467041015625, + "red": 1.6013128757476807, + "x": 1.6013128757476807, + "y": 0.2467041015625, + "z": 3.946338653564453 + }, + "queryAACube": { + "scale": 2.5651814937591553, + "x": 0.318722128868103, + "y": -1.0358866453170776, + "z": 2.663747787475586 + }, + "rotation": { + "w": 0.8220492601394653, + "x": -1.52587890625e-05, + "y": 0.5693598985671997, + "z": -0.0001068115234375 + }, + "script": "file:///C:/Users/wayne/development/tryAgainEntityScript.js", + "shapeType": "static-mesh", + "type": "Model", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}" + }, + { + "angularDamping": 0, + "clientOnly": false, + "color": { + "blue": 0, + "green": 0, + "red": 255 + }, + "created": "2018-08-29T22:57:33Z", + "dimensions": { + "blue": 0.20000000298023224, + "green": 0.20000000298023224, + "red": 0.20000000298023224, + "x": 0.20000000298023224, + "y": 0.20000000298023224, + "z": 0.20000000298023224 + }, + "id": "{86188ae0-6b36-4753-a5c0-0ba31b8ca89a}", + "lastEdited": 1535583477861108, + "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "name": "Particle Rotate", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 1.3116319179534912, + "green": 0, + "red": 2.705613613128662, + "x": 2.705613613128662, + "y": 0, + "z": 1.3116319179534912 + }, + "queryAACube": { + "scale": 0.3464101552963257, + "x": 2.5324084758758545, + "y": -0.17320507764816284, + "z": 1.1384267807006836 + }, + "rotation": { + "w": 0.9127794504165649, + "x": 0.2575265169143677, + "y": 0.15553522109985352, + "z": 0.2761729955673218 + }, + "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", + "scriptTimestamp": 1532724769253, + "shape": "Cube", + "type": "Box", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}", + "visible": false + }, + { + "angularDamping": 0, + "clientOnly": false, + "color": { + "blue": 0, + "green": 0, + "red": 255 + }, + "created": "2018-08-29T22:57:33Z", + "dimensions": { + "blue": 0.20000000298023224, + "green": 0.20000000298023224, + "red": 0.20000000298023224, + "x": 0.20000000298023224, + "y": 0.20000000298023224, + "z": 0.20000000298023224 + }, + "id": "{ffa954a9-43e4-47b1-82c9-b921ed3414b0}", + "lastEdited": 1535583477861316, + "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "name": "Particle Rotate", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 3.8216662406921387, + "green": 0.0772705078125, + "red": 1.2409718036651611, + "x": 1.2409718036651611, + "y": 0.0772705078125, + "z": 3.8216662406921387 + }, + "queryAACube": { + "scale": 0.3464101552963257, + "x": 1.0677666664123535, + "y": -0.09593456983566284, + "z": 3.648461103439331 + }, + "rotation": { + "w": 0.926024317741394, + "x": 0.20308232307434082, + "y": -0.010269343852996826, + "z": 0.3179827928543091 + }, + "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", + "scriptTimestamp": 1532724769253, + "shape": "Cube", + "type": "Box", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}", + "visible": false + }, + { + "angularDamping": 0, + "clientOnly": false, + "color": { + "blue": 0, + "green": 0, + "red": 255 + }, + "created": "2018-08-29T22:57:33Z", + "dimensions": { + "blue": 0.20000000298023224, + "green": 0.20000000298023224, + "red": 0.20000000298023224, + "x": 0.20000000298023224, + "y": 0.20000000298023224, + "z": 0.20000000298023224 + }, + "id": "{e86df231-a55a-4ca7-ae68-d3271a543d10}", + "lastEdited": 1535583477860886, + "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "name": "Particle Rotate", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 3.8216662406921387, + "green": 0, + "red": 1.2409718036651611, + "x": 1.2409718036651611, + "y": 0, + "z": 3.8216662406921387 + }, + "queryAACube": { + "scale": 0.3464101552963257, + "x": 1.0677666664123535, + "y": -0.17320507764816284, + "z": 3.648461103439331 + }, + "rotation": { + "w": 0.6444342136383057, + "x": -0.08220034837722778, + "y": -0.6649118661880493, + "z": 0.3684900999069214 + }, + "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", + "scriptTimestamp": 1532724769253, + "shape": "Cube", + "type": "Box", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}", + "visible": false + }, + { + "angularDamping": 0, + "clientOnly": false, + "color": { + "blue": 0, + "green": 0, + "red": 255 + }, + "created": "2018-08-29T22:57:33Z", + "dimensions": { + "blue": 0.20000000298023224, + "green": 0.20000000298023224, + "red": 0.20000000298023224, + "x": 0.20000000298023224, + "y": 0.20000000298023224, + "z": 0.20000000298023224 + }, + "id": "{252ffb06-db92-4732-9315-7ee293c24ab8}", + "lastEdited": 1535583477862267, + "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "name": "Particle Rotate", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 1.3116319179534912, + "green": 0.15618896484375, + "red": 2.705613613128662, + "x": 2.705613613128662, + "y": 0.15618896484375, + "z": 1.3116319179534912 + }, + "queryAACube": { + "scale": 0.3464101552963257, + "x": 2.5324084758758545, + "y": -0.017016112804412842, + "z": 1.1384267807006836 + }, + "rotation": { + "w": 0.46953535079956055, + "x": -0.16719311475753784, + "y": -0.7982757091522217, + "z": 0.3380941152572632 + }, + "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", + "scriptTimestamp": 1532724769253, + "shape": "Cube", + "type": "Box", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}", + "visible": false + }, + { + "clientOnly": false, + "color": { + "blue": 0, + "green": 0, + "red": 0 + }, + "created": "2018-08-29T22:57:33Z", + "dimensions": { + "blue": 11.117486953735352, + "green": 3.580313205718994, + "red": 0.20000000298023224, + "x": 0.20000000298023224, + "y": 3.580313205718994, + "z": 11.117486953735352 + }, + "id": "{1c93807b-311d-48cd-af5e-b477d33b2811}", + "lastEdited": 1535583477860455, + "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 5.268576622009277, + "green": 1.1588134765625, + "red": 6.100250244140625, + "x": 6.100250244140625, + "y": 1.1588134765625, + "z": 5.268576622009277 + }, + "queryAACube": { + "scale": 11.681488037109375, + "x": 0.2595062255859375, + "y": -4.6819305419921875, + "z": -0.5721673965454102 + }, + "rotation": { + "w": 0.9662165641784668, + "x": -4.57763671875e-05, + "y": -0.2576791048049927, + "z": 1.52587890625e-05 + }, + "shape": "Cube", + "type": "Box", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}", + "visible": false + }, + { + "alpha": 0, + "alphaFinish": 0, + "alphaStart": 1, + "clientOnly": false, + "color": { + "blue": 255, + "green": 205, + "red": 3 + }, + "colorFinish": { + "blue": 0, + "green": 0, + "red": 0, + "x": 0, + "y": 0, + "z": 0 + }, + "colorStart": { + "blue": 255, + "green": 204, + "red": 0, + "x": 0, + "y": 204, + "z": 255 + }, + "created": "2018-08-29T22:57:33Z", + "dimensions": { + "blue": 2.5, + "green": 2.5, + "red": 2.5, + "x": 2.5, + "y": 2.5, + "z": 2.5 + }, + "emitAcceleration": { + "blue": 0, + "green": 0, + "red": 0, + "x": 0, + "y": 0, + "z": 0 + }, + "emitDimensions": { + "blue": 1, + "green": 1, + "red": 1, + "x": 1, + "y": 1, + "z": 1 + }, + "emitOrientation": { + "w": 0.9993909597396851, + "x": 0.034897372126579285, + "y": -1.525880907138344e-05, + "z": -1.525880907138344e-05 + }, + "emitRate": 2, + "emitSpeed": 0, + "emitterShouldTrail": true, + "id": "{4cb534d1-5494-4aaa-aa28-ff5cee6e0b8f}", + "lastEdited": 1535583477862081, + "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "lifespan": 10, + "maxParticles": 40, + "name": "Rays", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "particleRadius": 0.75, + "polarFinish": 3.1415927410125732, + "position": { + "blue": 3.814434051513672, + "green": 1.44122314453125, + "red": 1.2319090366363525, + "x": 1.2319090366363525, + "y": 1.44122314453125, + "z": 3.814434051513672 + }, + "queryAACube": { + "scale": 4.330127239227295, + "x": -0.9331545829772949, + "y": -0.7238404750823975, + "z": 1.6493704319000244 + }, + "radiusFinish": 0.10000000149011612, + "radiusStart": 0, + "rotation": { + "w": 0.9594720602035522, + "x": -1.52587890625e-05, + "y": 0.28178834915161133, + "z": -4.57763671875e-05 + }, + "script": "file:///C:/Users/wayne/development/raysTryAgainEntityScript.js", + "speedSpread": 0, + "spinFinish": null, + "spinStart": null, + "textures": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/stripe.png", + "type": "ParticleEffect", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}" + }, + { + "clientOnly": false, + "color": { + "blue": 0, + "green": 0, + "red": 0 + }, + "created": "2018-08-29T22:57:33Z", + "dimensions": { + "blue": 11.117486953735352, + "green": 3.580313205718994, + "red": 0.20000000298023224, + "x": 0.20000000298023224, + "y": 3.580313205718994, + "z": 11.117486953735352 + }, + "id": "{a58a8ffe-17ee-4154-b8bb-54e2f0ca9a9d}", + "lastEdited": 1535583477862953, + "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 6.1806135177612305, + "green": 1.1588134765625, + "red": 1.4755167961120605, + "x": 1.4755167961120605, + "y": 1.1588134765625, + "z": 6.1806135177612305 + }, + "queryAACube": { + "scale": 11.681488037109375, + "x": -4.365227222442627, + "y": -4.6819305419921875, + "z": 0.33986949920654297 + }, + "rotation": { + "w": 0.8637980222702026, + "x": -4.57763671875e-05, + "y": 0.5038070678710938, + "z": -1.52587890625e-05 + }, + "shape": "Cube", + "type": "Box", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}", + "visible": false + }, + { + "alpha": 0, + "alphaFinish": 0, + "alphaStart": 0.25, + "clientOnly": false, + "colorFinish": { + "blue": 0, + "green": 0, + "red": 0, + "x": 0, + "y": 0, + "z": 0 + }, + "colorStart": { + "blue": 255, + "green": 255, + "red": 255, + "x": 255, + "y": 255, + "z": 255 + }, + "created": "2018-08-29T22:57:33Z", + "dimensions": { + "blue": 13.24000072479248, + "green": 13.24000072479248, + "red": 13.24000072479248, + "x": 13.24000072479248, + "y": 13.24000072479248, + "z": 13.24000072479248 + }, + "emitAcceleration": { + "blue": 0, + "green": 0.10000000149011612, + "red": 0, + "x": 0, + "y": 0.10000000149011612, + "z": 0 + }, + "emitDimensions": { + "blue": 1, + "green": 1, + "red": 1, + "x": 1, + "y": 1, + "z": 1 + }, + "emitOrientation": { + "w": 1, + "x": -1.52587890625e-05, + "y": -1.52587890625e-05, + "z": -1.52587890625e-05 + }, + "emitRate": 6, + "emitSpeed": 0, + "emitterShouldTrail": true, + "id": "{b6c56e83-f098-422d-a0e8-fd1497c62fbe}", + "lastEdited": 1535583477863251, + "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "lifespan": 10, + "maxParticles": 10, + "name": "Stars", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "particleRadius": 0.07000000029802322, + "polarFinish": 3.1415927410125732, + "position": { + "blue": 3.78922963142395, + "green": 0.5220947265625, + "red": 1.1928560733795166, + "x": 1.1928560733795166, + "y": 0.5220947265625, + "z": 3.78922963142395 + }, + "queryAACube": { + "scale": 22.932353973388672, + "x": -10.273321151733398, + "y": -10.944082260131836, + "z": -7.676947593688965 + }, + "radiusFinish": 0, + "radiusStart": 0, + "rotation": { + "w": 0.996429443359375, + "x": -1.52587890625e-05, + "y": -0.08442819118499756, + "z": -4.57763671875e-05 + }, + "speedSpread": 0, + "spinFinish": null, + "spinStart": null, + "textures": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/star.png", + "type": "ParticleEffect", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}" + }, + { + "alpha": 0, + "alphaFinish": 0, + "alphaStart": 1, + "clientOnly": false, + "color": { + "blue": 211, + "green": 227, + "red": 104 + }, + "colorFinish": { + "blue": 0, + "green": 0, + "red": 0, + "x": 0, + "y": 0, + "z": 0 + }, + "colorStart": { + "blue": 211, + "green": 227, + "red": 104, + "x": 104, + "y": 227, + "z": 211 + }, + "created": "2018-08-29T22:57:33Z", + "dimensions": { + "blue": 2.5, + "green": 2.5, + "red": 2.5, + "x": 2.5, + "y": 2.5, + "z": 2.5 + }, + "emitAcceleration": { + "blue": 0, + "green": 0, + "red": 0, + "x": 0, + "y": 0, + "z": 0 + }, + "emitDimensions": { + "blue": 1, + "green": 1, + "red": 1, + "x": 1, + "y": 1, + "z": 1 + }, + "emitOrientation": { + "w": 0.9993909597396851, + "x": 0.034897372126579285, + "y": -1.525880907138344e-05, + "z": -1.525880907138344e-05 + }, + "emitRate": 2, + "emitSpeed": 0, + "id": "{f87fab56-c8d8-4ff8-abf0-35a76dfccf2b}", + "lastEdited": 1535583477862685, + "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "lifespan": 10, + "maxParticles": 40, + "name": "Rays", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "particleRadius": 0.75, + "polarFinish": 3.1415927410125732, + "position": { + "blue": 1.3553659915924072, + "green": 1.44122314453125, + "red": 2.572803497314453, + "x": 2.572803497314453, + "y": 1.44122314453125, + "z": 1.3553659915924072 + }, + "queryAACube": { + "scale": 4.330127239227295, + "x": 0.40773987770080566, + "y": -0.7238404750823975, + "z": -0.8096976280212402 + }, + "radiusFinish": 0.10000000149011612, + "radiusStart": 0, + "rotation": { + "w": 0.9803768396377563, + "x": -1.52587890625e-05, + "y": 0.19707024097442627, + "z": -7.62939453125e-05 + }, + "script": "file:///C:/Users/wayne/development/raysBackEntityScript.js", + "speedSpread": 0, + "spinFinish": null, + "spinStart": null, + "textures": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/stripe.png", + "type": "ParticleEffect", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}" + }, + { + "clientOnly": false, + "created": "2018-08-29T22:57:33Z", + "dimensions": { + "blue": 2.1097896099090576, + "green": 0.04847164824604988, + "red": 1.458284616470337, + "x": 1.458284616470337, + "y": 0.04847164824604988, + "z": 2.1097896099090576 + }, + "id": "{1af53cfc-0cce-467a-96e0-a937f2651ce2}", + "lastEdited": 1535583477863389, + "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "modelURL": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/portal2.fbx", + "name": "Back", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 1.5835940837860107, + "green": 0.2467041015625, + "red": 3.0345542430877686, + "x": 3.0345542430877686, + "y": 0.2467041015625, + "z": 1.5835940837860107 + }, + "queryAACube": { + "scale": 2.5651814937591553, + "x": 1.751963496208191, + "y": -1.0358866453170776, + "z": 0.3010033369064331 + }, + "rotation": { + "w": 0.9084458351135254, + "x": -1.52587890625e-05, + "y": 0.4179598093032837, + "z": -0.0001068115234375 + }, + "script": "file:///C:/Users/wayne/development/tryAgainEntityScript.js", + "shapeType": "static-mesh", + "type": "Model", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}" + } + ], + "Id": "{351e561a-ee5e-4e8b-87ab-d28677d3b374}", + "Version": 93 +} From a5243fbd7e5048c0a17ed28d1b712e5a713298c2 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Wed, 29 Aug 2018 16:12:50 -0700 Subject: [PATCH 156/545] commenting out notification for script --- scripts/system/notifications.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/notifications.js b/scripts/system/notifications.js index 0778e2a44b..13d500b909 100644 --- a/scripts/system/notifications.js +++ b/scripts/system/notifications.js @@ -624,7 +624,7 @@ Controller.keyReleaseEvent.connect(keyReleaseEvent); Script.update.connect(update); Script.scriptEnding.connect(scriptEnding); - Window.domainConnectionRefused.connect(onDomainConnectionRefused); + //Window.domainConnectionRefused.connect(onDomainConnectionRefused); Window.stillSnapshotTaken.connect(onSnapshotTaken); Window.snapshot360Taken.connect(onSnapshotTaken); Window.processingGifStarted.connect(processingGif); From 9fb0f8b7c00fef665b94b7e56005063b394832f0 Mon Sep 17 00:00:00 2001 From: Angus Antley Date: Thu, 30 Aug 2018 00:25:53 +0100 Subject: [PATCH 157/545] added condition to prevent overwriting tracker input with estimated orientation for spine2 joint --- interface/src/avatar/MySkeletonModel.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 8fd7d31956..77d1a87195 100644 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -239,7 +239,10 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { params.primaryControllerFlags[Rig::PrimaryControllerType_Hips] = (uint8_t)Rig::ControllerFlags::Enabled | (uint8_t)Rig::ControllerFlags::Estimated; // set spine2 if we have hand controllers - if (myAvatar->getControllerPoseInAvatarFrame(controller::Action::RIGHT_HAND).isValid() && myAvatar->getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND).isValid()) { + if (myAvatar->getControllerPoseInAvatarFrame(controller::Action::RIGHT_HAND).isValid() && + myAvatar->getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND).isValid() && + !(params.primaryControllerFlags[Rig::PrimaryControllerType_Spine2] & (uint8_t)Rig::ControllerFlags::Enabled)) { + AnimPose currentSpine2Pose; AnimPose currentHeadPose; AnimPose currentHipsPose; From aaf5f593c598ab1b0df24b89a2cbf52beac39e86 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 29 Aug 2018 14:29:15 -0700 Subject: [PATCH 158/545] send MyAvatar avatar entity updates through entity tree --- interface/src/AvatarBookmarks.cpp | 18 ++--------- interface/src/avatar/MyAvatar.cpp | 52 +++++++++++++++++++++++++------ interface/src/avatar/MyAvatar.h | 5 ++- 3 files changed, 48 insertions(+), 27 deletions(-) diff --git a/interface/src/AvatarBookmarks.cpp b/interface/src/AvatarBookmarks.cpp index 4119b843e1..5c79bedc9a 100644 --- a/interface/src/AvatarBookmarks.cpp +++ b/interface/src/AvatarBookmarks.cpp @@ -145,20 +145,9 @@ void AvatarBookmarks::removeBookmark(const QString& bookmarkName) { emit bookmarkDeleted(bookmarkName); } -bool isWearableEntity(const EntityItemPointer& entity) { - return entity->isVisible() && (entity->getParentJointIndex() != INVALID_JOINT_INDEX || (entity->getType() == EntityTypes::Model && (std::static_pointer_cast(entity))->getRelayParentJoints())) - && (entity->getParentID() == DependencyManager::get()->getSessionUUID() || entity->getParentID() == DependencyManager::get()->getMyAvatar()->getSelfID()); -} - void AvatarBookmarks::updateAvatarEntities(const QVariantList &avatarEntities) { auto myAvatar = DependencyManager::get()->getMyAvatar(); - auto treeRenderer = DependencyManager::get(); - EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr; - myAvatar->removeAvatarEntities([&](const QUuid& entityID) { - auto entity = entityTree->findEntityByID(entityID); - return entity && isWearableEntity(entity); - }); - + myAvatar->removeWearableAvatarEntities(); addAvatarEntities(avatarEntities); } @@ -183,10 +172,7 @@ void AvatarBookmarks::loadBookmark(const QString& bookmarkName) { auto myAvatar = DependencyManager::get()->getMyAvatar(); auto treeRenderer = DependencyManager::get(); EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr; - myAvatar->removeAvatarEntities([&](const QUuid& entityID) { - auto entity = entityTree->findEntityByID(entityID); - return entity && isWearableEntity(entity); - }); + myAvatar->removeWearableAvatarEntities(); const QString& avatarUrl = bookmark.value(ENTRY_AVATAR_URL, "").toString(); myAvatar->useFullAvatarURL(avatarUrl); qCDebug(interfaceapp) << "Avatar On " << avatarUrl; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 923d071cc0..7bf18f468c 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1703,18 +1703,50 @@ void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) { emit skeletonChanged(); } -void MyAvatar::removeAvatarEntities(const std::function& condition) { +bool isWearableEntity(const EntityItemPointer& entity) { + return entity->isVisible() + && (entity->getParentJointIndex() != INVALID_JOINT_INDEX + || (entity->getType() == EntityTypes::Model && (std::static_pointer_cast(entity))->getRelayParentJoints())) + && (entity->getParentID() == DependencyManager::get()->getSessionUUID() + || entity->getParentID() == AVATAR_SELF_ID); +} + +void MyAvatar::clearAvatarEntities() { auto treeRenderer = DependencyManager::get(); EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr; - if (entityTree) { - entityTree->withWriteLock([&] { - AvatarEntityMap avatarEntities = getAvatarEntityData(); - for (auto entityID : avatarEntities.keys()) { - if (!condition || condition(entityID)) { - entityTree->deleteEntity(entityID, true, true); - } - } + + AvatarEntityMap avatarEntities = getAvatarEntityData(); + for (auto entityID : avatarEntities.keys()) { + entityTree->withWriteLock([&entityID, &entityTree] { + // remove this entity first from the entity tree + entityTree->deleteEntity(entityID, true, true); }); + + // remove the avatar entity from our internal list + // (but indicate it doesn't need to be pulled from the tree) + clearAvatarEntity(entityID, false); + } +} + +void MyAvatar::removeWearableAvatarEntities() { + auto treeRenderer = DependencyManager::get(); + EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr; + + if (entityTree) { + AvatarEntityMap avatarEntities = getAvatarEntityData(); + for (auto entityID : avatarEntities.keys()) { + auto entity = entityTree->findEntityByID(entityID); + if (entity && isWearableEntity(entity)) { + entityTree->withWriteLock([&entityID, &entityTree] { + // remove this entity first from the entity tree + entityTree->deleteEntity(entityID, true, true); + }); + + // remove the avatar entity from our internal list + // (but indicate it doesn't need to be pulled from the tree) + clearAvatarEntity(entityID, false); + } + } } } @@ -2116,7 +2148,7 @@ void MyAvatar::setAttachmentData(const QVector& attachmentData) } // clear any existing avatar entities - setAvatarEntityData(AvatarEntityMap()); + clearAvatarEntities(); for (auto& properties : newEntitiesProperties) { DependencyManager::get()->addEntity(properties, true); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index ba6348cc22..bb0df1af62 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -931,7 +931,8 @@ public: * @returns {object[]} */ Q_INVOKABLE QVariantList getAvatarEntitiesVariant(); - void removeAvatarEntities(const std::function& condition = {}); + void clearAvatarEntities(); + void removeWearableAvatarEntities(); /**jsdoc * @function MyAvatar.isFlying @@ -1782,4 +1783,6 @@ void audioListenModeFromScriptValue(const QScriptValue& object, AudioListenerMod QScriptValue driveKeysToScriptValue(QScriptEngine* engine, const MyAvatar::DriveKeys& driveKeys); void driveKeysFromScriptValue(const QScriptValue& object, MyAvatar::DriveKeys& driveKeys); +bool isWearableEntity(const EntityItemPointer& entity); + #endif // hifi_MyAvatar_h From eb29c9c4a298bd13ec87832800edb1a24597e748 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Wed, 29 Aug 2018 16:53:22 -0700 Subject: [PATCH 159/545] updating with default landing location --- interface/resources/serverless/redirect.json | 130 ++++++++++--------- interface/src/Application.cpp | 1 - 2 files changed, 67 insertions(+), 64 deletions(-) diff --git a/interface/resources/serverless/redirect.json b/interface/resources/serverless/redirect.json index 9e3b29cc26..71dfae4212 100644 --- a/interface/resources/serverless/redirect.json +++ b/interface/resources/serverless/redirect.json @@ -23,9 +23,9 @@ "blue": 4.54052734375, "green": 1.722428798675537, "red": 4.593362331390381, - "x": 4.593362331390381, - "y": 1.722428798675537, - "z": 4.54052734375 + "x": 0.5933623313903809, + "y": -7.777571201324463, + "z": 0.54052734375 }, "queryAACube": { "scale": 0.8152676820755005, @@ -65,9 +65,9 @@ "blue": 3.9590959548950195, "green": 1.738053798675537, "red": 5.0181121826171875, - "x": 5.0181121826171875, - "y": 1.738053798675537, - "z": 3.9590959548950195 + "x": 1.0181121826171875, + "y": -7.761946201324463, + "z": -0.04090404510498047 }, "queryAACube": { "scale": 0.8152676820755005, @@ -106,9 +106,9 @@ "blue": 2.3440732955932617, "green": 1.7684326171875, "red": 1.8812973499298096, - "x": 1.8812973499298096, - "y": 1.7684326171875, - "z": 2.3440732955932617 + "x": -2.1187026500701904, + "y": -7.7315673828125, + "z": -1.6559267044067383 }, "queryAACube": { "scale": 24.9415340423584, @@ -194,9 +194,9 @@ "blue": 1.3712034225463867, "green": 0.5220947265625, "red": 2.6281180381774902, - "x": 2.6281180381774902, - "y": 0.5220947265625, - "z": 1.3712034225463867 + "x": -1.3718819618225098, + "y": -8.9779052734375, + "z": -2.6287965774536133 }, "queryAACube": { "scale": 22.932353973388672, @@ -243,9 +243,9 @@ "blue": 1.9063844680786133, "green": 1.15850830078125, "red": 0.16632509231567383, - "x": 0.16632509231567383, - "y": 1.15850830078125, - "z": 1.9063844680786133 + "x": -3.833674907684326, + "y": -8.34149169921875, + "z": -2.0936155319213867 }, "queryAACube": { "scale": 11.681488037109375, @@ -290,9 +290,9 @@ "blue": 1.3116319179534912, "green": 0.0772705078125, "red": 2.705613613128662, - "x": 2.705613613128662, - "y": 0.0772705078125, - "z": 1.3116319179534912 + "x": -1.294386386871338, + "y": -9.4227294921875, + "z": -2.688368082046509 }, "queryAACube": { "scale": 0.3464101552963257, @@ -334,9 +334,9 @@ "blue": 4.2324604988098145, "green": 0.17547607421875, "red": 4.802988529205322, - "x": 4.802988529205322, - "y": 0.17547607421875, - "z": 4.2324604988098145 + "x": 0.8029885292053223, + "y": -9.32452392578125, + "z": 0.23246049880981445 }, "queryAACube": { "scale": 12.771358489990234, @@ -375,9 +375,9 @@ "blue": 1.45927095413208, "green": 1.6763916015625, "red": 0, - "x": 0, - "y": 1.6763916015625, - "z": 1.45927095413208 + "x": -4, + "y": -7.8236083984375, + "z": -2.54072904586792 }, "queryAACube": { "scale": 3.6522583961486816, @@ -420,9 +420,9 @@ "blue": 3.8216662406921387, "green": 0.15618896484375, "red": 1.2409718036651611, - "x": 1.2409718036651611, - "y": 0.15618896484375, - "z": 3.8216662406921387 + "x": -2.759028196334839, + "y": -9.34381103515625, + "z": -0.17833375930786133 }, "queryAACube": { "scale": 0.3464101552963257, @@ -467,9 +467,9 @@ "blue": 0, "green": 1.1583251953125, "red": 4.971565246582031, - "x": 4.971565246582031, - "y": 1.1583251953125, - "z": 0 + "x": 0.9715652465820312, + "y": -8.3416748046875, + "z": -4 }, "queryAACube": { "scale": 11.681488037109375, @@ -509,9 +509,9 @@ "blue": 3.946338653564453, "green": 0.2467041015625, "red": 1.6013128757476807, - "x": 1.6013128757476807, - "y": 0.2467041015625, - "z": 3.946338653564453 + "x": -2.3986871242523193, + "y": -9.2532958984375, + "z": -0.053661346435546875 }, "queryAACube": { "scale": 2.5651814937591553, @@ -556,9 +556,9 @@ "blue": 1.3116319179534912, "green": 0, "red": 2.705613613128662, - "x": 2.705613613128662, - "y": 0, - "z": 1.3116319179534912 + "x": -1.294386386871338, + "y": -9.5, + "z": -2.688368082046509 }, "queryAACube": { "scale": 0.3464101552963257, @@ -605,9 +605,9 @@ "blue": 3.8216662406921387, "green": 0.0772705078125, "red": 1.2409718036651611, - "x": 1.2409718036651611, - "y": 0.0772705078125, - "z": 3.8216662406921387 + "x": -2.759028196334839, + "y": -9.4227294921875, + "z": -0.17833375930786133 }, "queryAACube": { "scale": 0.3464101552963257, @@ -654,9 +654,9 @@ "blue": 3.8216662406921387, "green": 0, "red": 1.2409718036651611, - "x": 1.2409718036651611, - "y": 0, - "z": 3.8216662406921387 + "x": -2.759028196334839, + "y": -9.5, + "z": -0.17833375930786133 }, "queryAACube": { "scale": 0.3464101552963257, @@ -703,9 +703,9 @@ "blue": 1.3116319179534912, "green": 0.15618896484375, "red": 2.705613613128662, - "x": 2.705613613128662, - "y": 0.15618896484375, - "z": 1.3116319179534912 + "x": -1.294386386871338, + "y": -9.34381103515625, + "z": -2.688368082046509 }, "queryAACube": { "scale": 0.3464101552963257, @@ -750,9 +750,9 @@ "blue": 5.268576622009277, "green": 1.1588134765625, "red": 6.100250244140625, - "x": 6.100250244140625, - "y": 1.1588134765625, - "z": 5.268576622009277 + "x": 2.100250244140625, + "y": -8.3411865234375, + "z": 1.2685766220092773 }, "queryAACube": { "scale": 11.681488037109375, @@ -844,9 +844,9 @@ "blue": 3.814434051513672, "green": 1.44122314453125, "red": 1.2319090366363525, - "x": 1.2319090366363525, - "y": 1.44122314453125, - "z": 3.814434051513672 + "x": -2.7680909633636475, + "y": -8.05877685546875, + "z": -0.18556594848632812 }, "queryAACube": { "scale": 4.330127239227295, @@ -894,9 +894,9 @@ "blue": 6.1806135177612305, "green": 1.1588134765625, "red": 1.4755167961120605, - "x": 1.4755167961120605, - "y": 1.1588134765625, - "z": 6.1806135177612305 + "x": -2.5244832038879395, + "y": -8.3411865234375, + "z": 2.1806135177612305 }, "queryAACube": { "scale": 11.681488037109375, @@ -983,9 +983,9 @@ "blue": 3.78922963142395, "green": 0.5220947265625, "red": 1.1928560733795166, - "x": 1.1928560733795166, - "y": 0.5220947265625, - "z": 3.78922963142395 + "x": -2.8071439266204834, + "y": -8.9779052734375, + "z": -0.2107703685760498 }, "queryAACube": { "scale": 22.932353973388672, @@ -1080,9 +1080,9 @@ "blue": 1.3553659915924072, "green": 1.44122314453125, "red": 2.572803497314453, - "x": 2.572803497314453, - "y": 1.44122314453125, - "z": 1.3553659915924072 + "x": -1.4271965026855469, + "y": -8.05877685546875, + "z": -2.6446340084075928 }, "queryAACube": { "scale": 4.330127239227295, @@ -1127,9 +1127,9 @@ "blue": 1.5835940837860107, "green": 0.2467041015625, "red": 3.0345542430877686, - "x": 3.0345542430877686, - "y": 0.2467041015625, - "z": 1.5835940837860107 + "x": -0.9654457569122314, + "y": -9.2532958984375, + "z": -2.4164059162139893 }, "queryAACube": { "scale": 2.5651814937591553, @@ -1149,6 +1149,10 @@ "userData": "{\"grabbableKey\":{\"grabbable\":false}}" } ], + "Paths": + { + "/": "/1.46,-9,0.7/0,0.487,0,0.86663" + }, "Id": "{351e561a-ee5e-4e8b-87ab-d28677d3b374}", "Version": 93 } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6e15cc0dd8..348d1d5690 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2369,7 +2369,6 @@ void Application::domainConnectionRedirect(const QString& reasonMessage, int rea addressManager->handleLookupString(REDIRECT_HIFI_ADDRESS); getMyAvatar()->setWorldVelocity(glm::vec3(0.0f)); // in (w, x, y, z) component-structure for the constructor - getMyAvatar()->setWorldOrientation(glm::quat(0.8775935173034668f, 0.0f, 0.4794054925441742f, 0.0f)); break; } default: From b8cd5dd8b97fef9a22fee72dcc5a13df69b7a6e7 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 29 Aug 2018 16:58:19 -0700 Subject: [PATCH 160/545] Fixup PR13870: Make the feature work in Master --- interface/src/Application.cpp | 10 +++++----- libraries/networking/src/AccountManager.h | 3 ++- scripts/system/commerce/wallet.js | 6 ++++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 44bba6250b..af29ea0bd1 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1735,11 +1735,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo QTimer* settingsTimer = new QTimer(); moveToNewNamedThread(settingsTimer, "Settings Thread", [this, settingsTimer]{ connect(qApp, &Application::beforeAboutToQuit, [this, settingsTimer]{ - bool autoLogout = Setting::Handle(AUTO_LOGOUT_SETTING_NAME, false).get(); - if (autoLogout) { - auto accountManager = DependencyManager::get(); - accountManager->logout(); - } // Disconnect the signal from the save settings QObject::disconnect(settingsTimer, &QTimer::timeout, this, &Application::saveSettings); // Stop the settings timer @@ -2491,6 +2486,11 @@ void Application::cleanupBeforeQuit() { } DependencyManager::destroy(); + bool autoLogout = Setting::Handle(AUTO_LOGOUT_SETTING_NAME, false).get(); + if (autoLogout) { + DependencyManager::get()->removeAccountFromFile(); + } + _displayPlugin.reset(); PluginManager::getInstance()->shutdown(); diff --git a/libraries/networking/src/AccountManager.h b/libraries/networking/src/AccountManager.h index a79b69fe2b..b122115dd0 100644 --- a/libraries/networking/src/AccountManager.h +++ b/libraries/networking/src/AccountManager.h @@ -96,6 +96,8 @@ public: QUrl getMetaverseServerURL() { return NetworkingConstants::METAVERSE_SERVER_URL(); } + void removeAccountFromFile(); + public slots: void requestAccessToken(const QString& login, const QString& password); void requestAccessTokenWithSteam(QByteArray authSessionTicket); @@ -133,7 +135,6 @@ private: void operator=(AccountManager const& other) = delete; void persistAccountToFile(); - void removeAccountFromFile(); void passSuccessToCallback(QNetworkReply* reply); void passErrorToCallback(QNetworkReply* reply); diff --git a/scripts/system/commerce/wallet.js b/scripts/system/commerce/wallet.js index 8730273e7c..5939b36438 100644 --- a/scripts/system/commerce/wallet.js +++ b/scripts/system/commerce/wallet.js @@ -407,8 +407,10 @@ } function onUsernameChanged() { - Settings.setValue("wallet/autoLogout", false); - Settings.setValue("wallet/savedUsername", ""); + if (Account.username !== Settings.getValue("wallet/savedUsername")) { + Settings.setValue("wallet/autoLogout", false); + Settings.setValue("wallet/savedUsername", ""); + } } // Function Name: fromQml() From 4844f06e5e172e6b2e1b61f694145d5f5dbe649b Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 29 Aug 2018 17:33:39 -0700 Subject: [PATCH 161/545] brain freeze --- interface/src/LODManager.cpp | 4 +--- scripts/developer/utilities/lib/plotperf/PlotPerf.qml | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index ce674f7295..df371f3a59 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -105,9 +105,7 @@ void LODManager::autoAdjustLOD(float realTimeDelta) { auto error = (targetFPS - currentFPS) / targetFPS; error = glm::clamp(error, -1.0f, 1.0f); - if (error <= 0.0f) { - // error = error * 2.0f; - } + auto integral = previous_integral + error * dt; glm::clamp(integral, -1.0f, 1.0f); diff --git a/scripts/developer/utilities/lib/plotperf/PlotPerf.qml b/scripts/developer/utilities/lib/plotperf/PlotPerf.qml index 46056be5fd..27101a2867 100644 --- a/scripts/developer/utilities/lib/plotperf/PlotPerf.qml +++ b/scripts/developer/utilities/lib/plotperf/PlotPerf.qml @@ -186,10 +186,10 @@ Item { } function pixelFromVal(val, valScale) { - return lineHeight + (height - lineHeight) * (1 - (0.9) * (val - _displayMinValue) / (_displayMaxValue - _displayMinValue)); + return lineHeight + (height - lineHeight) * (1 - (0.99) * (val - _displayMinValue) / (_displayMaxValue - _displayMinValue)); } function valueFromPixel(pixY) { - return _displayMinValue + (((pixY - lineHeight) / (height - lineHeight) - 1) * (_displayMaxValue - _displayMinValue) / (-0.9)); + return _displayMinValue + (((pixY - lineHeight) / (height - lineHeight) - 1) * (_displayMaxValue - _displayMinValue) / (-0.99)); } function plotValueHistory(ctx, valHistory, color) { var widthStep= width / (valHistory.length - 1); From a186be014da18676776ae88865d3d45a9008d961 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 29 Aug 2018 17:35:28 -0700 Subject: [PATCH 162/545] Use std::chrono for usecTimestampNow() --- libraries/shared/src/SharedUtil.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libraries/shared/src/SharedUtil.cpp b/libraries/shared/src/SharedUtil.cpp index bb22a1e753..3bef7f7e18 100644 --- a/libraries/shared/src/SharedUtil.cpp +++ b/libraries/shared/src/SharedUtil.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include @@ -132,6 +133,9 @@ static std::once_flag usecTimestampNowIsInitialized; static QElapsedTimer timestampTimer; quint64 usecTimestampNow(bool wantDebug) { + using namespace std::chrono; + return duration_cast(high_resolution_clock::now().time_since_epoch()).count(); +#if 0 std::call_once(usecTimestampNowIsInitialized, [&] { TIME_REFERENCE = QDateTime::currentMSecsSinceEpoch() * USECS_PER_MSEC; // ms to usec timestampTimer.start(); @@ -203,6 +207,7 @@ quint64 usecTimestampNow(bool wantDebug) { } return now; +#endif } float secTimestampNow() { From 248c2621a43a6b9dc67e9d6002f7aa7f77e769e4 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 29 Aug 2018 17:57:54 -0700 Subject: [PATCH 163/545] fix blendshapes crash --- .../render-utils/src/CauterizedModel.cpp | 5 +- libraries/render-utils/src/Model.cpp | 87 +++++++++---------- libraries/render-utils/src/Model.h | 2 + 3 files changed, 45 insertions(+), 49 deletions(-) diff --git a/libraries/render-utils/src/CauterizedModel.cpp b/libraries/render-utils/src/CauterizedModel.cpp index 3966d04b6d..259036f500 100644 --- a/libraries/render-utils/src/CauterizedModel.cpp +++ b/libraries/render-utils/src/CauterizedModel.cpp @@ -86,9 +86,8 @@ void CauterizedModel::createRenderItemSet() { // Create the render payloads int numParts = (int)mesh->getNumParts(); for (int partIndex = 0; partIndex < numParts; partIndex++) { - if (!fbxGeometry.meshes[i].blendshapes.empty() && !_blendedVertexBuffers[i]) { - _blendedVertexBuffers[i] = std::make_shared(); - _blendedVertexBuffers[i]->resize(fbxGeometry.meshes[i].vertices.size() * (sizeof(glm::vec3) + 2 * sizeof(NormalType))); + if (!fbxGeometry.meshes[i].blendshapes.empty()) { + initializeBlendshapes(fbxGeometry.meshes[i], i); } auto ptr = std::make_shared(shared_from_this(), i, partIndex, shapeID, transform, offset); _modelMeshRenderItems << std::static_pointer_cast(ptr); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 71250c6483..946275a312 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -302,52 +302,11 @@ bool Model::updateGeometry() { assert(_meshStates.empty()); const FBXGeometry& fbxGeometry = getFBXGeometry(); - int i = 0; foreach (const FBXMesh& mesh, fbxGeometry.meshes) { MeshState state; state.clusterDualQuaternions.resize(mesh.clusters.size()); state.clusterMatrices.resize(mesh.clusters.size()); _meshStates.push_back(state); - - if (!mesh.blendshapes.isEmpty()) { - if (!_blendedVertexBuffers[i]) { - _blendedVertexBuffers[i] = std::make_shared(); - } - const auto& buffer = _blendedVertexBuffers[i]; - QVector normalsAndTangents; - normalsAndTangents.resize(2 * mesh.normals.size()); - - // Interleave normals and tangents - // Parallel version for performance - tbb::parallel_for(tbb::blocked_range(0, mesh.normals.size()), [&](const tbb::blocked_range& range) { - auto normalsRange = std::make_pair(mesh.normals.begin() + range.begin(), mesh.normals.begin() + range.end()); - auto tangentsRange = std::make_pair(mesh.tangents.begin() + range.begin(), mesh.tangents.begin() + range.end()); - auto normalsAndTangentsIt = normalsAndTangents.begin() + 2 * range.begin(); - - for (auto normalIt = normalsRange.first, tangentIt = tangentsRange.first; - normalIt != normalsRange.second; - ++normalIt, ++tangentIt) { -#if FBX_PACK_NORMALS - glm::uint32 finalNormal; - glm::uint32 finalTangent; - buffer_helpers::packNormalAndTangent(*normalIt, *tangentIt, finalNormal, finalTangent); -#else - const auto& finalNormal = *normalIt; - const auto& finalTangent = *tangentIt; -#endif - *normalsAndTangentsIt = finalNormal; - ++normalsAndTangentsIt; - *normalsAndTangentsIt = finalTangent; - ++normalsAndTangentsIt; - } - }); - const auto verticesSize = mesh.vertices.size() * sizeof(glm::vec3); - buffer->resize(mesh.vertices.size() * sizeof(glm::vec3) + normalsAndTangents.size() * sizeof(NormalType)); - buffer->setSubData(0, verticesSize, (const gpu::Byte*) mesh.vertices.constData()); - buffer->setSubData(verticesSize, 2 * mesh.normals.size() * sizeof(NormalType), (const gpu::Byte*) normalsAndTangents.data()); - mesh.normalsAndTangents = normalsAndTangents; - } - i++; } needFullUpdate = true; emit rigReady(); @@ -1514,10 +1473,10 @@ void Model::setBlendedVertices(int blendNumber, const Geometry::WeakPointer& geo assert(buffer); buffer->resize(mesh.vertices.size() * sizeof(glm::vec3) + mesh.normalsAndTangents.size() * sizeof(NormalType)); buffer->setSubData(0, verticesSize, (gpu::Byte*) vertices.constData() + index * sizeof(glm::vec3)); - buffer->setSubData(verticesSize, 2 * mesh.normals.size() * sizeof(NormalType), (const gpu::Byte*) normalsAndTangents.data() + normalAndTangentIndex * sizeof(NormalType)); + buffer->setSubData(verticesSize, mesh.normalsAndTangents.size() * sizeof(NormalType), (const gpu::Byte*) normalsAndTangents.data() + normalAndTangentIndex * sizeof(NormalType)); index += vertexCount; - normalAndTangentIndex += 2 * mesh.normals.size(); + normalAndTangentIndex += mesh.normalsAndTangents.size(); } } @@ -1555,6 +1514,42 @@ const render::ItemIDs& Model::fetchRenderItemIDs() const { return _modelMeshRenderItemIDs; } +void Model::initializeBlendshapes(const FBXMesh& mesh, int index) { + QVector normalsAndTangents; + normalsAndTangents.resize(2 * mesh.normals.size()); + + // Interleave normals and tangents + // Parallel version for performance + tbb::parallel_for(tbb::blocked_range(0, mesh.normals.size()), [&](const tbb::blocked_range& range) { + auto normalsRange = std::make_pair(mesh.normals.begin() + range.begin(), mesh.normals.begin() + range.end()); + auto tangentsRange = std::make_pair(mesh.tangents.begin() + range.begin(), mesh.tangents.begin() + range.end()); + auto normalsAndTangentsIt = normalsAndTangents.begin() + 2 * range.begin(); + + for (auto normalIt = normalsRange.first, tangentIt = tangentsRange.first; + normalIt != normalsRange.second; + ++normalIt, ++tangentIt) { +#if FBX_PACK_NORMALS + glm::uint32 finalNormal; + glm::uint32 finalTangent; + buffer_helpers::packNormalAndTangent(*normalIt, *tangentIt, finalNormal, finalTangent); +#else + const auto& finalNormal = *normalIt; + const auto& finalTangent = *tangentIt; +#endif + *normalsAndTangentsIt = finalNormal; + ++normalsAndTangentsIt; + *normalsAndTangentsIt = finalTangent; + ++normalsAndTangentsIt; + } + }); + const auto verticesSize = mesh.vertices.size() * sizeof(glm::vec3); + _blendedVertexBuffers[index] = std::make_shared(); + _blendedVertexBuffers[index]->resize(mesh.vertices.size() * sizeof(glm::vec3) + normalsAndTangents.size() * sizeof(NormalType)); + _blendedVertexBuffers[index]->setSubData(0, verticesSize, (const gpu::Byte*) mesh.vertices.constData()); + _blendedVertexBuffers[index]->setSubData(verticesSize, normalsAndTangents.size() * sizeof(NormalType), (const gpu::Byte*) normalsAndTangents.data()); + mesh.normalsAndTangents = normalsAndTangents; +} + void Model::createRenderItemSet() { assert(isLoaded()); const auto& meshes = _renderGeometry->getMeshes(); @@ -1583,7 +1578,7 @@ void Model::createRenderItemSet() { // Run through all of the meshes, and place them into their segregated, but unsorted buckets int shapeID = 0; uint32_t numMeshes = (uint32_t)meshes.size(); - auto fbxGeometry = getFBXGeometry(); + auto& fbxGeometry = getFBXGeometry(); for (uint32_t i = 0; i < numMeshes; i++) { const auto& mesh = meshes.at(i); if (!mesh) { @@ -1593,8 +1588,8 @@ void Model::createRenderItemSet() { // Create the render payloads int numParts = (int)mesh->getNumParts(); for (int partIndex = 0; partIndex < numParts; partIndex++) { - if (fbxGeometry.meshes[i].blendshapes.empty() && !_blendedVertexBuffers[i]) { - _blendedVertexBuffers[i] = std::make_shared(); + if (!fbxGeometry.meshes[i].blendshapes.empty()) { + initializeBlendshapes(fbxGeometry.meshes[i], i); } _modelMeshRenderItems << std::make_shared(shared_from_this(), i, partIndex, shapeID, transform, offset); auto material = getGeometry()->getShapeMaterial(shapeID); diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 677be61261..eaca068c10 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -482,6 +482,8 @@ protected: bool shouldInvalidatePayloadShapeKey(int meshIndex); + void initializeBlendshapes(const FBXMesh& mesh, int index); + private: float _loadingPriority { 0.0f }; From 7b7f369c394edd715d2e143cce321324f4d5dfff Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 29 Aug 2018 18:25:10 -0700 Subject: [PATCH 164/545] Further reductions in shared pointers, getWorldPosition(). --- .../src/avatars/AvatarMixerClientData.cpp | 4 +++ .../src/avatars/AvatarMixerClientData.h | 1 + .../src/avatars/AvatarMixerSlave.cpp | 34 +++++++++---------- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixerClientData.cpp b/assignment-client/src/avatars/AvatarMixerClientData.cpp index e003fdd769..1dd4cc769b 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.cpp +++ b/assignment-client/src/avatars/AvatarMixerClientData.cpp @@ -218,6 +218,10 @@ uint16_t AvatarMixerClientData::getLastBroadcastSequenceNumber(const QUuid& node } void AvatarMixerClientData::ignoreOther(SharedNodePointer self, SharedNodePointer other) { + ignoreOther(self.data(), other.data()); +} + +void AvatarMixerClientData::ignoreOther(const Node* self, const Node* other) { if (!isRadiusIgnoring(other->getUUID())) { addToRadiusIgnoringSet(other->getUUID()); auto killPacket = NLPacket::create(PacketType::KillAvatar, NUM_BYTES_RFC4122_UUID + sizeof(KillAvatarReason), true); diff --git a/assignment-client/src/avatars/AvatarMixerClientData.h b/assignment-client/src/avatars/AvatarMixerClientData.h index a892455fe3..7d203bd771 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.h +++ b/assignment-client/src/avatars/AvatarMixerClientData.h @@ -95,6 +95,7 @@ public: void addToRadiusIgnoringSet(const QUuid& other) { _radiusIgnoredOthers.insert(other); } void removeFromRadiusIgnoringSet(SharedNodePointer self, const QUuid& other); void ignoreOther(SharedNodePointer self, SharedNodePointer other); + void ignoreOther(const Node* self, const Node* other); void readViewFrustumPacket(const QByteArray& message); diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index f0c291b2c2..e772fa4d08 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -213,7 +213,7 @@ void AvatarMixerSlave::broadcastAvatarData(const SharedNodePointer& node) { } void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) { - const Node* nodeRaw = node.data(); + const Node* destinationNode = node.data(); auto nodeList = DependencyManager::get(); @@ -224,7 +224,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) _stats.nodesBroadcastedTo++; - AvatarMixerClientData* nodeData = reinterpret_cast(nodeRaw->getLinkedData()); + AvatarMixerClientData* nodeData = reinterpret_cast(destinationNode->getLinkedData()); nodeData->resetInViewStats(); @@ -264,7 +264,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) bool PALIsOpen = nodeData->getRequestsDomainListData(); // When this is true, the AvatarMixer will send Avatar data to a client about avatars that have ignored them - bool getsAnyIgnored = PALIsOpen && nodeRaw->getCanKick(); + bool getsAnyIgnored = PALIsOpen && destinationNode->getCanKick(); if (PALIsOpen) { // Increase minimumBytesPerAvatar if the PAL is open @@ -291,14 +291,12 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // setup list of AvatarData as well as maps to map betweeen the AvatarData and the original nodes struct AvatarSortData { - AvatarSortData(const SharedNodePointer& nodeShared, AvatarData* avatarData, quint64 lastEncodeTime) - : _nodeShared(nodeShared) - , _node(nodeShared.data()) + AvatarSortData(const Node* node, AvatarData* avatarData, quint64 lastEncodeTime) + : _node(node) , _avatarData(avatarData) , _lastEncodeTime(lastEncodeTime) { } - const SharedNodePointer& _nodeShared; - Node* _node; + const Node* _node; AvatarData* _avatarData; quint64 _lastEncodeTime; }; @@ -315,7 +313,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) AvatarData* otherAvatar = otherNodeData->getAvatarSharedPointer().get(); auto lastEncodeTime = nodeData->getLastOtherAvatarEncodeTime(otherAvatar->getSessionUUID()); - avatarsToSort.emplace_back(AvatarSortData(otherNode, otherAvatar, lastEncodeTime)); + avatarsToSort.emplace_back(AvatarSortData(otherNodeRaw, otherAvatar, lastEncodeTime)); } }); @@ -326,7 +324,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) : _avatar(avatar), _node(avatarNode), _lastEncodeTime(lastEncodeTime) {} glm::vec3 getPosition() const override { return _avatar->getClientGlobalPosition(); } float getRadius() const override { - glm::vec3 nodeBoxHalfScale = (_avatar->getWorldPosition() - _avatar->getGlobalBoundingBoxCorner() * _avatar->getSensorToWorldScale()); + glm::vec3 nodeBoxHalfScale = (_avatar->getClientGlobalPosition() - _avatar->getGlobalBoundingBoxCorner() * _avatar->getSensorToWorldScale()); return glm::max(nodeBoxHalfScale.x, glm::max(nodeBoxHalfScale.y, nodeBoxHalfScale.z)); } uint64_t getTimestamp() const override { @@ -350,7 +348,8 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // ignore or sort for (const auto& avatar : avatarsToSort) { - if (avatar._node == nodeRaw) { + auto avatarNode = avatar._node; + if (avatarNode == destinationNode) { // don't echo updates to self continue; } @@ -362,7 +361,6 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // happen if for example the avatar is connected on a desktop and sending // updates at ~30hz. So every 3 frames we skip a frame. - auto avatarNode = avatar._node; assert(avatarNode); // we can't have gotten here without the avatarData being a valid key in the map const AvatarMixerClientData* avatarNodeData = reinterpret_cast(avatarNode->getLinkedData()); @@ -372,13 +370,13 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // make sure we have data for this avatar, that it isn't the same node, // and isn't an avatar that the viewing node has ignored // or that has ignored the viewing node - if ((nodeRaw->isIgnoringNodeWithID(avatarNode->getUUID()) && !PALIsOpen) - || (avatarNode->isIgnoringNodeWithID(nodeRaw->getUUID()) && !getsAnyIgnored)) { + if ((destinationNode->isIgnoringNodeWithID(avatarNode->getUUID()) && !PALIsOpen) + || (avatarNode->isIgnoringNodeWithID(destinationNode->getUUID()) && !getsAnyIgnored)) { shouldIgnore = true; } else { // Check to see if the space bubble is enabled // Don't bother with these checks if the other avatar has their bubble enabled and we're gettingAnyIgnored - if (nodeRaw->isIgnoreRadiusEnabled() || (avatarNode->isIgnoreRadiusEnabled() && !getsAnyIgnored)) { + if (destinationNode->isIgnoreRadiusEnabled() || (avatarNode->isIgnoreRadiusEnabled() && !getsAnyIgnored)) { float sensorToWorldScale = avatarNodeData->getAvatarSharedPointer()->getSensorToWorldScale(); // Define the scale of the box for the current other node glm::vec3 otherNodeBoxScale = (avatarNodeData->getPosition() - avatarNodeData->getGlobalBoundingBoxCorner()) * 2.0f * sensorToWorldScale; @@ -394,7 +392,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // Perform the collision check between the two bounding boxes if (nodeBox.touches(otherNodeBox)) { - nodeData->ignoreOther(node, avatar._nodeShared); + nodeData->ignoreOther(destinationNode, avatarNode); shouldIgnore = !getsAnyIgnored; } } @@ -576,7 +574,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) _stats.numBytesSent += numAvatarDataBytes; // send the avatar data PacketList - nodeList->sendPacketList(std::move(avatarPacketList), *nodeRaw); + nodeList->sendPacketList(std::move(avatarPacketList), *destinationNode); // record the bytes sent for other avatar data in the AvatarMixerClientData nodeData->recordSentAvatarData(numAvatarDataBytes); @@ -586,7 +584,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) if (traitsPacketList->getNumPackets() >= 1) { // send the traits packet list - nodeList->sendPacketList(std::move(traitsPacketList), *nodeRaw); + nodeList->sendPacketList(std::move(traitsPacketList), *destinationNode); } // record the number of avatars held back this frame From 6583864597136a7b41ab7abe0613b825333510b7 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Wed, 29 Aug 2018 19:19:20 -0700 Subject: [PATCH 165/545] AVX2 implementation of interleave_4x4() --- libraries/audio/src/AudioHRTF.cpp | 6 +++- libraries/audio/src/avx2/AudioHRTF_avx2.cpp | 37 +++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/libraries/audio/src/AudioHRTF.cpp b/libraries/audio/src/AudioHRTF.cpp index 0f87df2346..655527a65c 100644 --- a/libraries/audio/src/AudioHRTF.cpp +++ b/libraries/audio/src/AudioHRTF.cpp @@ -453,8 +453,12 @@ static void FIR_1x4(float* src, float* dst0, float* dst1, float* dst2, float* ds (*f)(src, dst0, dst1, dst2, dst3, coef, numFrames); // dispatch } +void interleave_4x4_AVX2(float* src0, float* src1, float* src2, float* src3, float* dst, int numFrames); + static void interleave_4x4(float* src0, float* src1, float* src2, float* src3, float* dst, int numFrames) { - interleave_4x4_SSE(src0, src1, src2, src3, dst, numFrames); + + static auto f = cpuSupportsAVX2() ? interleave_4x4_AVX2 : interleave_4x4_SSE; + (*f)(src0, src1, src2, src3, dst, numFrames); // dispatch } void biquad2_4x4_AVX2(float* src, float* dst, float coef[5][8], float state[3][8], int numFrames); diff --git a/libraries/audio/src/avx2/AudioHRTF_avx2.cpp b/libraries/audio/src/avx2/AudioHRTF_avx2.cpp index 0c3c6b5096..9000df367f 100644 --- a/libraries/audio/src/avx2/AudioHRTF_avx2.cpp +++ b/libraries/audio/src/avx2/AudioHRTF_avx2.cpp @@ -87,6 +87,43 @@ void FIR_1x4_AVX2(float* src, float* dst0, float* dst1, float* dst2, float* dst3 _mm256_zeroupper(); } +// 4 channel planar to interleaved +void interleave_4x4_AVX2(float* src0, float* src1, float* src2, float* src3, float* dst, int numFrames) { + + assert(numFrames % 8 == 0); + + for (int i = 0; i < numFrames; i += 8) { + + __m256 x0 = _mm256_loadu_ps(&src0[i]); + __m256 x1 = _mm256_loadu_ps(&src1[i]); + __m256 x2 = _mm256_loadu_ps(&src2[i]); + __m256 x3 = _mm256_loadu_ps(&src3[i]); + + // interleave (4x4 matrix transpose) + __m256 t0 = _mm256_unpacklo_ps(x0, x1); + __m256 t1 = _mm256_unpackhi_ps(x0, x1); + __m256 t2 = _mm256_unpacklo_ps(x2, x3); + __m256 t3 = _mm256_unpackhi_ps(x2, x3); + + x0 = _mm256_shuffle_ps(t0, t2, _MM_SHUFFLE(1,0,1,0)); + x1 = _mm256_shuffle_ps(t0, t2, _MM_SHUFFLE(3,2,3,2)); + x2 = _mm256_shuffle_ps(t1, t3, _MM_SHUFFLE(1,0,1,0)); + x3 = _mm256_shuffle_ps(t1, t3, _MM_SHUFFLE(3,2,3,2)); + + t0 = _mm256_permute2f128_ps(x0, x1, 0x20); + t1 = _mm256_permute2f128_ps(x2, x3, 0x20); + t2 = _mm256_permute2f128_ps(x0, x1, 0x31); + t3 = _mm256_permute2f128_ps(x2, x3, 0x31); + + _mm256_storeu_ps(&dst[4*i+0], t0); + _mm256_storeu_ps(&dst[4*i+8], t1); + _mm256_storeu_ps(&dst[4*i+16], t2); + _mm256_storeu_ps(&dst[4*i+24], t3); + } + + _mm256_zeroupper(); +} + // process 2 cascaded biquads on 4 channels (interleaved) // biquads are computed in parallel, by adding one sample of delay void biquad2_4x4_AVX2(float* src, float* dst, float coef[5][8], float state[3][8], int numFrames) { From 6c502e79e350924d5006d457c22ea85f8995d0d9 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 29 Aug 2018 22:56:44 -0700 Subject: [PATCH 166/545] Fine tuning a LOD regulator PV that works --- interface/src/LODManager.cpp | 102 ++++-------- interface/src/LODManager.h | 15 +- .../utilities/lib/plotperf/PlotPerf.qml | 6 +- scripts/developer/utilities/render/lod.qml | 153 +++++++++++------- 4 files changed, 139 insertions(+), 137 deletions(-) diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index df371f3a59..df3b9a9f69 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -66,14 +66,23 @@ void LODManager::setRenderTimes(float presentTime, float engineRunTime, float ba } void LODManager::autoAdjustLOD(float realTimeDelta) { - // float maxRenderTime = glm::max(glm::max(_presentTime, _engineRunTime), _gpuTime); - float maxRenderTime = glm::max(glm::max(_presentTime, _engineRunTime), _gpuTime); + // The "render time" is the worse of: + // - engineRunTime: Time spent in the render thread in the engine producing the gpu::Frame N + // - batchTime: Time spent in the present thread processing the batches of gpu::Frame N+1 + // - presentTime: Time spent in the present thread between the last 2 swap buffers considered the total time to submit gpu::Frame N+1 + // - gpuTime: Time spent in the GPU executing the gpu::Frame N + 2 + + // But Present time is in reality synched with the monitor/display refresh rate, it s always longer than batchTime. + // So if batchTime is fast enough relative to PResent Time we are using it, otherwise we are using presentTime. got it ? + auto presentTime = (_presentTime - _batchTime > 3.0f ? _batchTime + 3.0f : _presentTime); + float maxRenderTime = glm::max(glm::max(presentTime, _engineRunTime), _gpuTime); + // compute time-weighted running average maxRenderTime // Note: we MUST clamp the blend to 1.0 for stability float blend = (realTimeDelta < LOD_ADJUST_RUNNING_AVG_TIMESCALE) ? realTimeDelta / LOD_ADJUST_RUNNING_AVG_TIMESCALE : 1.0f; _avgRenderTime = (1.0f - blend) * _avgRenderTime + blend * maxRenderTime; // msec - float smoothBlend = (realTimeDelta < LOD_ADJUST_RUNNING_AVG_TIMESCALE * _pidCoefs.w) ? realTimeDelta / (LOD_ADJUST_RUNNING_AVG_TIMESCALE * _pidCoefs.w) : 1.0f; + float smoothBlend = (realTimeDelta < LOD_ADJUST_RUNNING_AVG_TIMESCALE * _smoothScale) ? realTimeDelta / (LOD_ADJUST_RUNNING_AVG_TIMESCALE * _smoothScale) : 1.0f; _smoothRenderTime = (1.0f - smoothBlend) * _smoothRenderTime + smoothBlend * maxRenderTime; // msec @@ -87,24 +96,29 @@ void LODManager::autoAdjustLOD(float realTimeDelta) { float oldSolidAngle = getLODAngleDeg(); float targetFPS = 0.5 * (getLODDecreaseFPS() + getLODIncreaseFPS()); - // float targetFPS = (getLODDecreaseFPS()); float targetPeriod = 1.0f / targetFPS; float currentFPS = (float)MSECS_PER_SECOND / _avgRenderTime; + float currentSmoothFPS = (float)MSECS_PER_SECOND / _smoothRenderTime; + float currentVarianceFPS = (currentSmoothFPS - currentFPS); + currentVarianceFPS *= currentVarianceFPS; - static uint64_t lastTime = usecTimestampNow(); + auto dt = realTimeDelta; - uint64_t now = usecTimestampNow(); - auto dt = (float) ((now - lastTime) / double(USECS_PER_MSEC)); - // if (dt < targetPeriod * _pidCoefs.w) return; - dt = realTimeDelta; - - lastTime = now; auto previous_error = _pidHistory.x; auto previous_integral = _pidHistory.y; - auto error = (targetFPS - currentFPS) / targetFPS; - error = glm::clamp(error, -1.0f, 1.0f); + auto smoothError = (targetFPS - currentSmoothFPS); + + auto fpsError = smoothError; + + auto errorSquare = smoothError * smoothError; + + auto noiseCoef = (errorSquare < _pidCoefs.w * currentVarianceFPS ? 0.0f : 1.0f); + + auto normalizedError = noiseCoef * smoothError / targetFPS; + + auto error = glm::clamp(normalizedError, -1.0f, 1.0f); auto integral = previous_integral + error * dt; glm::clamp(integral, -1.0f, 1.0f); @@ -131,59 +145,6 @@ void LODManager::autoAdjustLOD(float realTimeDelta) { setLODAngleDeg(newSolidAngle); - //newSolidAngle = std::max( 0.5f, std::min(newSolidAngle, 90.f)); - - //auto halTan = glm::tan(glm::radians(newSolidAngle * 0.5f)); - - //auto octreeSizeScale = TREE_SCALE * OCTREE_TO_MESH_RATIO / halTan; - // _octreeSizeScale = octreeSizeScale; -/* - if (currentFPS < getLODDecreaseFPS()) { - if (now > _decreaseFPSExpiry) { - _decreaseFPSExpiry = now + LOD_AUTO_ADJUST_PERIOD; - if (_octreeSizeScale > ADJUST_LOD_MIN_SIZE_SCALE) { - _octreeSizeScale *= LOD_AUTO_ADJUST_DECREMENT_FACTOR; - if (_octreeSizeScale < ADJUST_LOD_MIN_SIZE_SCALE) { - _octreeSizeScale = ADJUST_LOD_MIN_SIZE_SCALE; - } - emit LODDecreased(); - emit LODChanged(); - // Assuming the LOD adjustment will work: we optimistically reset _avgRenderTime - // to provide an FPS just above the decrease threshold. It will drift close to its - // true value after a few LOD_ADJUST_TIMESCALEs and we'll adjust again as necessary. - _avgRenderTime = (float)MSECS_PER_SECOND / (getLODDecreaseFPS() + 1.0f); - } - _decreaseFPSExpiry = now + LOD_AUTO_ADJUST_PERIOD; - } - _increaseFPSExpiry = now + LOD_AUTO_ADJUST_PERIOD; - } else if (currentFPS > getLODIncreaseFPS()) { - if (now > _increaseFPSExpiry) { - _increaseFPSExpiry = now + LOD_AUTO_ADJUST_PERIOD; - if (_octreeSizeScale < ADJUST_LOD_MAX_SIZE_SCALE) { - if (_octreeSizeScale < ADJUST_LOD_MIN_SIZE_SCALE) { - _octreeSizeScale = ADJUST_LOD_MIN_SIZE_SCALE; - } else { - _octreeSizeScale *= LOD_AUTO_ADJUST_INCREMENT_FACTOR; - } - if (_octreeSizeScale > ADJUST_LOD_MAX_SIZE_SCALE) { - _octreeSizeScale = ADJUST_LOD_MAX_SIZE_SCALE; - } - emit LODIncreased(); - emit LODChanged(); - - // Assuming the LOD adjustment will work: we optimistically reset _avgRenderTime - // to provide an FPS just below the increase threshold. It will drift close to its - // true value after a few LOD_ADJUST_TIMESCALEs and we'll adjust again as necessary. - _avgRenderTime = (float)MSECS_PER_SECOND / (getLODIncreaseFPS() - 1.0f); - } - _increaseFPSExpiry = now + LOD_AUTO_ADJUST_PERIOD; - } - _decreaseFPSExpiry = now + LOD_AUTO_ADJUST_PERIOD; - } else { - _increaseFPSExpiry = now + LOD_AUTO_ADJUST_PERIOD; - _decreaseFPSExpiry = _increaseFPSExpiry; - } -*/ if (oldOctreeSizeScale != _octreeSizeScale) { auto lodToolsDialog = DependencyManager::get()->getLodToolsDialog(); if (lodToolsDialog) { @@ -325,6 +286,11 @@ void LODManager::saveSettings() { hmdLODDecreaseFPS.set(getHMDLODDecreaseFPS()); } + +void LODManager::setSmoothScale(float t) { + _smoothScale = glm::max(1.0f, t); +} + void LODManager::setWorldDetailQuality(float quality) { static const float MAX_DESKTOP_FPS = 60; @@ -414,7 +380,7 @@ float LODManager::getPidKi() const { float LODManager::getPidKd() const { return _pidCoefs.z; } -float LODManager::getPidT() const { +float LODManager::getPidKv() const { return _pidCoefs.w; } void LODManager::setPidKp(float k) { @@ -426,7 +392,7 @@ void LODManager::setPidKi(float k) { void LODManager::setPidKd(float k) { _pidCoefs.z = k; } -void LODManager::setPidT(float t) { +void LODManager::setPidKv(float t) { _pidCoefs.w = t; } diff --git a/interface/src/LODManager.h b/interface/src/LODManager.h index 167533a236..6843744d16 100644 --- a/interface/src/LODManager.h +++ b/interface/src/LODManager.h @@ -67,6 +67,7 @@ class LODManager : public QObject, public Dependency { Q_PROPERTY(float smoothRenderTime READ getSmoothRenderTime) Q_PROPERTY(float smoothFPS READ getSmoothFPS) + Q_PROPERTY(float smoothScale READ getSmoothScale WRITE setSmoothScale) Q_PROPERTY(float lodLevel READ getLODLevel WRITE setLODLevel NOTIFY LODChanged) Q_PROPERTY(float lodDecreaseFPS READ getLODDecreaseFPS) @@ -80,7 +81,7 @@ class LODManager : public QObject, public Dependency { Q_PROPERTY(float pidKp READ getPidKp WRITE setPidKp) Q_PROPERTY(float pidKi READ getPidKi WRITE setPidKi) Q_PROPERTY(float pidKd READ getPidKd WRITE setPidKd) - Q_PROPERTY(float pidT READ getPidT WRITE setPidT) + Q_PROPERTY(float pidKv READ getPidKv WRITE setPidKv) Q_PROPERTY(float pidOp READ getPidOp) Q_PROPERTY(float pidOi READ getPidOi) @@ -195,6 +196,9 @@ public: void saveSettings(); void resetLODAdjust(); + void setSmoothScale(float t); + float getSmoothScale() const { return _smoothScale; } + float getAverageRenderTime() const { return _avgRenderTime; }; float getMaxTheoreticalFPS() const { return (float)MSECS_PER_SECOND / _avgRenderTime; }; @@ -216,12 +220,12 @@ public: float getPidKp() const; float getPidKi() const; float getPidKd() const; - float getPidT() const; + float getPidKv() const; void setPidKp(float k); void setPidKi(float k); void setPidKd(float k); - void setPidT(float t); - + void setPidKv(float t); + float getPidOp() const; float getPidOi() const; float getPidOd() const; @@ -254,6 +258,7 @@ private: float _batchTime{ 0.0f }; // msec float _gpuTime { 0.0f }; // msec + float _smoothScale{ 8.0f }; float _avgRenderTime { 0.0f }; // msec float _smoothRenderTime{ 0.0f }; float _desktopMaxRenderTime { DEFAULT_DESKTOP_MAX_RENDER_TIME }; @@ -262,7 +267,7 @@ private: float _octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE; int _boundaryLevelAdjust = 0; - glm::vec4 _pidCoefs{ 1.0f, 0.0000000f, 0.f, 8.0f }; + glm::vec4 _pidCoefs{ 1.0f, 0.0f, 0.0f, 1.0f }; // Kp, Ki, Kd, Kv glm::vec4 _pidHistory{ 0.0f }; glm::vec4 _pidOutputs{ 0.0f }; diff --git a/scripts/developer/utilities/lib/plotperf/PlotPerf.qml b/scripts/developer/utilities/lib/plotperf/PlotPerf.qml index 27101a2867..f239cc010a 100644 --- a/scripts/developer/utilities/lib/plotperf/PlotPerf.qml +++ b/scripts/developer/utilities/lib/plotperf/PlotPerf.qml @@ -217,9 +217,9 @@ Item { function displayTitle(ctx, text, maxVal) { ctx.fillStyle = "grey"; ctx.textAlign = "right"; - ctx.fillText("max" + displayValue(_displayMaxValue, root.valueUnit), width, pixelFromVal(_displayMaxValue)); + ctx.fillText("max " + displayValue(_displayMaxValue, root.valueUnit), width, pixelFromVal(_displayMaxValue)); - ctx.fillText("min" + displayValue(_displayMinValue, root.valueUnit), width, pixelFromVal(_displayMinValue)); + ctx.fillText("min " + displayValue(_displayMinValue, root.valueUnit), width, pixelFromVal(_displayMinValue)); ctx.fillStyle = "white"; ctx.textAlign = "left"; @@ -245,7 +245,6 @@ Item { ctx.strokeStyle= "LightSlateGray"; ctx.lineWidth="1"; - // ctx.strokeStyle= "grey"; ctx.beginPath(); ctx.moveTo(0, maxY); ctx.lineTo(width, maxY); @@ -254,7 +253,6 @@ Item { if (_displayMinValue != 0) { var zeroY = pixelFromVal(0); var minY = pixelFromVal(_displayMinValue); - // ctx.strokeStyle= "DarkRed"; ctx.beginPath(); ctx.moveTo(0, zeroY); ctx.lineTo(width, zeroY); diff --git a/scripts/developer/utilities/render/lod.qml b/scripts/developer/utilities/render/lod.qml index d0562e1020..28cf744394 100644 --- a/scripts/developer/utilities/render/lod.qml +++ b/scripts/developer/utilities/render/lod.qml @@ -53,18 +53,26 @@ Item { min: 0.25 integral: false - anchors.left: autoLOD.left + anchors.left: parent.left anchors.right: parent.right } - HifiControls.CheckBox { - id: autoLOD - boxSize: 20 - text: "Auto LOD" - checked: LODManager.automaticLODAdjust - onCheckedChanged: { LODManager.automaticLODAdjust = (checked) } + Row { + HifiControls.CheckBox { + id: autoLOD + boxSize: 20 + text: "Auto LOD" + checked: LODManager.automaticLODAdjust + onCheckedChanged: { LODManager.automaticLODAdjust = (checked) } + } + HifiControls.CheckBox { + id: showLODRegulatorDetails + visible: LODManager.automaticLODAdjust + boxSize: 20 + text: "Show LOD Details" + } } - + RichSlider { visible: !LODManager.automaticLODAdjust showLabel: true @@ -78,67 +86,85 @@ Item { anchors.left: parent.left anchors.right: parent.right } - - RichSlider { - visible: LODManager.automaticLODAdjust - showLabel: true - label: "LOD PID Kp" - valueVar: LODManager["pidKp"] - valueVarSetter: (function (v) { LODManager["pidKp"] = v }) - max: 2.0 - min: 0.0 - integral: false - numDigits: 3 - + Column { + id: lodRegulatorDetails + visible: LODManager.automaticLODAdjust && showLODRegulatorDetails.checked anchors.left: parent.left anchors.right: parent.right - } - RichSlider { - visible: LODManager.automaticLODAdjust - showLabel: true - label: "LOD PID Ki" - valueVar: LODManager["pidKi"] - valueVarSetter: (function (v) { LODManager["pidKi"] = v }) - max: 0.1 - min: 0.0 - integral: false - numDigits: 8 + RichSlider { + visible: lodRegulatorDetails.visible + showLabel: true + label: "LOD Kp" + valueVar: LODManager["pidKp"] + valueVarSetter: (function (v) { LODManager["pidKp"] = v }) + max: 2.0 + min: 0.0 + integral: false + numDigits: 3 - anchors.left: parent.left - anchors.right: parent.right - } - RichSlider { - visible: LODManager.automaticLODAdjust - showLabel: true - label: "LOD PID Kd" - valueVar: LODManager["pidKd"] - valueVarSetter: (function (v) { LODManager["pidKd"] = v }) - max: 10.0 - min: 0.0 - integral: false - numDigits: 3 + anchors.left: parent.left + anchors.right: parent.right + } + RichSlider { + visible: false && lodRegulatorDetails.visible + showLabel: true + label: "LOD Ki" + valueVar: LODManager["pidKi"] + valueVarSetter: (function (v) { LODManager["pidKi"] = v }) + max: 0.1 + min: 0.0 + integral: false + numDigits: 8 - anchors.left: parent.left - anchors.right: parent.right - } - RichSlider { - visible: LODManager.automaticLODAdjust - showLabel: true - label: "LOD PID Num T" - valueVar: LODManager["pidT"] - valueVarSetter: (function (v) { LODManager["pidT"] = v }) - max: 10.0 - min: 0.0 - integral: true + anchors.left: parent.left + anchors.right: parent.right + } + RichSlider { + visible: false && lodRegulatorDetails.visible + showLabel: true + label: "LOD Kd" + valueVar: LODManager["pidKd"] + valueVarSetter: (function (v) { LODManager["pidKd"] = v }) + max: 10.0 + min: 0.0 + integral: false + numDigits: 3 - anchors.left: parent.left - anchors.right: parent.right + anchors.left: parent.left + anchors.right: parent.right + } + RichSlider { + visible: lodRegulatorDetails.visible + showLabel: true + label: "LOD Kv" + valueVar: LODManager["pidKv"] + valueVarSetter: (function (v) { LODManager["pidKv"] = v }) + max: 2.0 + min: 0.0 + integral: false + + anchors.left: parent.left + anchors.right: parent.right + } + RichSlider { + visible: lodRegulatorDetails.visible + showLabel: true + label: "LOD Smooth Scale" + valueVar: LODManager["smoothScale"] + valueVarSetter: (function (v) { LODManager["smoothScale"] = v }) + max: 20.0 + min: 1.0 + integral: true + + anchors.left: parent.left + anchors.right: parent.right + } } } Column { id: stats - spacing: 8 + spacing: 4 anchors.right: parent.right anchors.left: parent.left anchors.top: topHeader.bottom @@ -146,7 +172,8 @@ Item { function evalEvenHeight() { // Why do we have to do that manually ? cannot seem to find a qml / anchor / layout mode that does that ? - return (height - topLine.height - bottomLine.height - spacing * (children.length - 3)) / (children.length - 2) + var numPlots = (children.length + (lodRegulatorDetails.visible ? 1 : 0) - 2) + return (height - topLine.height - bottomLine.height - spacing * (numPlots - 1)) / (numPlots) } Separator { @@ -226,6 +253,7 @@ Item { ] } PlotPerf { + // visible: lodRegulatorDetails.visible title: "PID Output" height: parent.evalEvenHeight() object: LODManager @@ -248,6 +276,11 @@ Item { prop: "pidOd", label: "Od", color: "#FF6666" + }, + { + prop: "pidO", + label: "Output", + color: "#66FF66" } ] } From 6c4862910e70fe0236b8ce9e4539a03c205fe802 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 30 Aug 2018 10:13:35 -0700 Subject: [PATCH 167/545] smoother edges for workload region feedback response --- libraries/workload/src/workload/ViewTask.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/workload/src/workload/ViewTask.cpp b/libraries/workload/src/workload/ViewTask.cpp index 27b136d64e..9d0c693149 100644 --- a/libraries/workload/src/workload/ViewTask.cpp +++ b/libraries/workload/src/workload/ViewTask.cpp @@ -135,15 +135,15 @@ glm::vec2 Regulator::run(const Timing_ns& deltaTime, const Timing_ns& measuredTi float noise = sqrtf(_measuredTimeNoiseSquared); // check budget - float budgetDelta = _budget.count() - _measuredTimeAverage; - if (abs(budgetDelta) < noise) { - // budget is within the noise + float offsetFromTarget = _budget.count() - _measuredTimeAverage; + if (fabsf(offsetFromTarget) < noise) { + // budget is within the noise --> do nothing return currentFrontBack; } - // clamp the step factor - glm::vec2 stepDelta = budgetDelta < 0.0f ? -_relativeStepDown : _relativeStepUp; - + // compute response + glm::vec2 stepDelta = offsetFromTarget < 0.0f ? -_relativeStepDown : _relativeStepUp; + stepDelta *= glm::min(1.0f, (fabsf(offsetFromTarget) - noise) / noise); // ease out of "do nothing" return currentFrontBack * (1.0f + stepDelta); } From 8b1fcfcce909c735b448df52b2ada545e0f042c1 Mon Sep 17 00:00:00 2001 From: David Back Date: Thu, 30 Aug 2018 10:16:27 -0700 Subject: [PATCH 168/545] fix double windows platform --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c365e61624..eae42ea32e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -913,7 +913,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { controller::StateController::setStateVariables({ { STATE_IN_HMD, STATE_CAMERA_FULL_SCREEN_MIRROR, STATE_CAMERA_FIRST_PERSON, STATE_CAMERA_THIRD_PERSON, STATE_CAMERA_ENTITY, STATE_CAMERA_INDEPENDENT, STATE_SNAP_TURN, STATE_ADVANCED_MOVEMENT_CONTROLS, STATE_GROUNDED, STATE_NAV_FOCUSED, - STATE_PLATFORM_WINDOWS, STATE_PLATFORM_MAC, STATE_PLATFORM_WINDOWS } }); + STATE_PLATFORM_WINDOWS, STATE_PLATFORM_MAC, STATE_PLATFORM_ANDROID } }); DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); From c2ac2b9ab0f56aae0e8e283d2508cce10f0df0b3 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Thu, 30 Aug 2018 10:59:55 -0700 Subject: [PATCH 169/545] Various tweaks; fix clang warning --- .../src/avatars/AvatarMixerClientData.cpp | 2 +- .../src/avatars/AvatarMixerClientData.h | 2 +- .../src/avatars/AvatarMixerSlave.cpp | 16 +++++++--------- libraries/shared/src/SharedUtil.cpp | 6 +++--- 4 files changed, 12 insertions(+), 14 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixerClientData.cpp b/assignment-client/src/avatars/AvatarMixerClientData.cpp index 1dd4cc769b..c54db90f5d 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.cpp +++ b/assignment-client/src/avatars/AvatarMixerClientData.cpp @@ -239,7 +239,7 @@ void AvatarMixerClientData::ignoreOther(const Node* self, const Node* other) { } } -void AvatarMixerClientData::removeFromRadiusIgnoringSet(SharedNodePointer self, const QUuid& other) { +void AvatarMixerClientData::removeFromRadiusIgnoringSet(const QUuid& other) { _radiusIgnoredOthers.erase(other); } diff --git a/assignment-client/src/avatars/AvatarMixerClientData.h b/assignment-client/src/avatars/AvatarMixerClientData.h index 7d203bd771..ee27f9bb0f 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.h +++ b/assignment-client/src/avatars/AvatarMixerClientData.h @@ -93,7 +93,7 @@ public: glm::vec3 getGlobalBoundingBoxCorner() const { return _avatar ? _avatar->getGlobalBoundingBoxCorner() : glm::vec3(0); } bool isRadiusIgnoring(const QUuid& other) const { return _radiusIgnoredOthers.find(other) != _radiusIgnoredOthers.end(); } void addToRadiusIgnoringSet(const QUuid& other) { _radiusIgnoredOthers.insert(other); } - void removeFromRadiusIgnoringSet(SharedNodePointer self, const QUuid& other); + void removeFromRadiusIgnoringSet(const QUuid& other); void ignoreOther(SharedNodePointer self, SharedNodePointer other); void ignoreOther(const Node* self, const Node* other); diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index e772fa4d08..34a429bea0 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -276,16 +276,16 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) auto avatarPacketList = NLPacketList::create(PacketType::BulkAvatarData); // Define the minimum bubble size - static const glm::vec3 minBubbleSize = avatar.getSensorToWorldScale() * glm::vec3(0.3f, 1.3f, 0.3f); + const glm::vec3 minBubbleSize = avatar.getSensorToWorldScale() * glm::vec3(0.3f, 1.3f, 0.3f); // Define the scale of the box for the current node - glm::vec3 nodeBoxScale = (nodeData->getPosition() - nodeData->getGlobalBoundingBoxCorner()) * 2.0f * avatar.getSensorToWorldScale(); + glm::vec3 nodeBoxScale = (avatar.getClientGlobalPosition() - avatar.getGlobalBoundingBoxCorner()) * 2.0f * avatar.getSensorToWorldScale(); // Set up the bounding box for the current node - AABox nodeBox(nodeData->getGlobalBoundingBoxCorner(), nodeBoxScale); + AABox nodeBox(avatar.getGlobalBoundingBoxCorner(), nodeBoxScale); // Clamp the size of the bounding box to a minimum scale if (glm::any(glm::lessThan(nodeBoxScale, minBubbleSize))) { nodeBox.setScaleStayCentered(minBubbleSize); } - // Quadruple the scale of both bounding boxes + // Quadruple the scale of first bounding box nodeBox.embiggen(4.0f); @@ -386,7 +386,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) if (glm::any(glm::lessThan(otherNodeBoxScale, minBubbleSize))) { otherNodeBox.setScaleStayCentered(minBubbleSize); } - // Change the scale of both bounding boxes + // Change the scale of other bounding box // (This is an arbitrary number determined empirically) otherNodeBox.embiggen(2.4f); @@ -398,7 +398,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) } // Not close enough to ignore if (!shouldIgnore) { - nodeData->removeFromRadiusIgnoringSet(node, avatarNode->getUUID()); + nodeData->removeFromRadiusIgnoringSet(avatarNode->getUUID()); } } @@ -439,6 +439,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) auto traitsPacketList = NLPacketList::create(PacketType::BulkAvatarTraits, QByteArray(), true, true); while (!sortedAvatars.empty()) { const Node* otherNode = sortedAvatars.top().getNode(); + auto lastEncodeForOther = sortedAvatars.top().getTimestamp(); sortedAvatars.pop(); remainingAvatars--; @@ -490,7 +491,6 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) } bool includeThisAvatar = true; - auto lastEncodeForOther = nodeData->getLastOtherAvatarEncodeTime(otherNode->getUUID()); QVector& lastSentJointsForOther = nodeData->getLastOtherAvatarSentJoints(otherNode->getUUID()); lastSentJointsForOther.resize(otherAvatar->getJointCount()); @@ -561,8 +561,6 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // use helper to add any changed traits to our packet list traitBytesSent += addChangedTraitsToBulkPacket(nodeData, otherNodeData, *traitsPacketList); - - traitsPacketList->getDataSize(); } quint64 startPacketSending = usecTimestampNow(); diff --git a/libraries/shared/src/SharedUtil.cpp b/libraries/shared/src/SharedUtil.cpp index 3bef7f7e18..a36bdb061e 100644 --- a/libraries/shared/src/SharedUtil.cpp +++ b/libraries/shared/src/SharedUtil.cpp @@ -128,9 +128,9 @@ void usecTimestampNowForceClockSkew(qint64 clockSkew) { ::usecTimestampNowAdjust = clockSkew; } -static std::atomic TIME_REFERENCE { 0 }; // in usec -static std::once_flag usecTimestampNowIsInitialized; -static QElapsedTimer timestampTimer; +//static std::atomic TIME_REFERENCE { 0 }; // in usec +//static std::once_flag usecTimestampNowIsInitialized; +//static QElapsedTimer timestampTimer; quint64 usecTimestampNow(bool wantDebug) { using namespace std::chrono; From b45b0f54e4ebd58d6ebe87e67c10a1089902d8bf Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Thu, 30 Aug 2018 11:59:53 -0700 Subject: [PATCH 170/545] Move unfilteredHandlers processing back into main loop --- libraries/networking/src/udt/Socket.cpp | 36 ++++++++++--------------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/libraries/networking/src/udt/Socket.cpp b/libraries/networking/src/udt/Socket.cpp index d764b9e8b2..44220df8f8 100644 --- a/libraries/networking/src/udt/Socket.cpp +++ b/libraries/networking/src/udt/Socket.cpp @@ -361,28 +361,6 @@ void Socket::processPendingDatagrams(int) { // setup a HifiSockAddr to read into HifiSockAddr senderSockAddr; - // Process unfiltered packets first. - for (auto datagramIter = _incomingDatagrams.begin(); datagramIter != _incomingDatagrams.end(); ++datagramIter) { - senderSockAddr.setAddress(datagramIter->_senderAddress); - senderSockAddr.setPort(datagramIter->_senderPort); - auto it = _unfilteredHandlers.find(senderSockAddr); - if (it != _unfilteredHandlers.end()) { - // we have a registered unfiltered handler for this HifiSockAddr (eg. STUN packet) - call that and return - if (it->second) { - auto basePacket = BasePacket::fromReceivedPacket(std::move(datagramIter->_datagram), - datagramIter->_datagramLength, - senderSockAddr); - basePacket->setReceiveTime(datagramIter->_receiveTime); - it->second(std::move(basePacket)); - } - - datagramIter = _incomingDatagrams.erase(datagramIter); - if (datagramIter == _incomingDatagrams.end()) { - break; - } - } - } - while (!_incomingDatagrams.empty()) { auto& datagram = _incomingDatagrams.front(); senderSockAddr.setAddress(datagram._senderAddress); @@ -397,6 +375,20 @@ void Socket::processPendingDatagrams(int) { _lastPacketSizeRead = datagramSize; _lastPacketSockAddr = senderSockAddr; + // Process unfiltered packets first. + auto it = _unfilteredHandlers.find(senderSockAddr); + if (it != _unfilteredHandlers.end()) { + // we have a registered unfiltered handler for this HifiSockAddr (eg. STUN packet) - call that and return + if (it->second) { + auto basePacket = BasePacket::fromReceivedPacket(std::move(datagram._datagram), + datagramSize, senderSockAddr); + basePacket->setReceiveTime(receiveTime); + it->second(std::move(basePacket)); + } + _incomingDatagrams.pop_front(); + continue; + } + // check if this was a control packet or a data packet bool isControlPacket = *reinterpret_cast(datagram._datagram.get()) & CONTROL_BIT_MASK; From 78c7948ebc374f78666a1978593f9dc4e9884cf2 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 30 Aug 2018 12:11:43 -0700 Subject: [PATCH 171/545] fine tuning the noise coef ramp and documenting the algorithm --- interface/src/LODManager.cpp | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index df3b9a9f69..925d48f9cd 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -100,8 +100,12 @@ void LODManager::autoAdjustLOD(float realTimeDelta) { float currentFPS = (float)MSECS_PER_SECOND / _avgRenderTime; float currentSmoothFPS = (float)MSECS_PER_SECOND / _smoothRenderTime; + + // Compute the Variance of the FPS signal (FPS - smouthFPS)^2 + // Also scale it by a percentage for fine tuning (default is 100%) float currentVarianceFPS = (currentSmoothFPS - currentFPS); currentVarianceFPS *= currentVarianceFPS; + currentVarianceFPS *= _pidCoefs.w; auto dt = realTimeDelta; @@ -114,11 +118,22 @@ void LODManager::autoAdjustLOD(float realTimeDelta) { auto errorSquare = smoothError * smoothError; - auto noiseCoef = (errorSquare < _pidCoefs.w * currentVarianceFPS ? 0.0f : 1.0f); + // Define a noiseCoef that is trying to adjust the error to the FPS target value based on its strength + // relative to the current Variance of the FPS signal. + // If the error is within the variance, just set to 0. + // if its within 2x the variance scale the control + // and full control if error is bigger than 2x variance + auto noiseCoef = 1.0f; + if (errorSquare < currentVarianceFPS) { + noiseCoef = 0.0f; + } else if (errorSquare < 2.0f * currentVarianceFPS) { + noiseCoef = (errorSquare - currentVarianceFPS) / currentVarianceFPS; + } - auto normalizedError = noiseCoef * smoothError / targetFPS; - - auto error = glm::clamp(normalizedError, -1.0f, 1.0f); + // The final normalized error is the the error to the FPS target, weighted by the noiseCoef, then normailzed by the target FPS. + // it s also clamped in the [-1, 1] range + auto error = noiseCoef * smoothError / targetFPS; + error = glm::clamp(error, -1.0f, 1.0f); auto integral = previous_integral + error * dt; glm::clamp(integral, -1.0f, 1.0f); From 93b0f151166d818fb019e4e2e48353d112738fcd Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Thu, 30 Aug 2018 13:22:17 -0700 Subject: [PATCH 172/545] addressing some feedback --- scripts/system/interstitialPage.js | 74 +++++++++++++++++------------- 1 file changed, 43 insertions(+), 31 deletions(-) diff --git a/scripts/system/interstitialPage.js b/scripts/system/interstitialPage.js index cf06e222c9..86a9e744e9 100644 --- a/scripts/system/interstitialPage.js +++ b/scripts/system/interstitialPage.js @@ -18,13 +18,13 @@ var MAX_X_SIZE = 3.8; var EPSILON = 0.01; var isVisible = false; - var STABILITY = 3.0; var VOLUME = 0.4; var tune = SoundCache.getSound("http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/crystals_and_voices.wav"); var sample = null; var MAX_LEFT_MARGIN = 1.9; var INNER_CIRCLE_WIDTH = 4.7; var DEFAULT_Z_OFFSET = 5.45; + var previousCameraMode = Camera.mode; var renderViewTask = Render.getConfig("RenderMainView"); var toolbar = Toolbars.getToolbar("com.highfidelity.interface.toolbar.system"); @@ -181,7 +181,7 @@ var TARGET_UPDATE_HZ = 60; // 50hz good enough, but we're using update var BASIC_TIMER_INTERVAL_MS = 1000 / TARGET_UPDATE_HZ; var lastInterval = Date.now(); - var currentDomain = ""; + var currentDomain = "no domain"; var timer = null; var target = 0; @@ -228,6 +228,8 @@ target = 0; currentProgress = 0.1; connectionToDomainFailed = false; + previousCameraMode = Camera.mode; + Camera.mode = "first person"; timer = Script.setTimeout(update, BASIC_TIMER_INTERVAL_MS); } } @@ -249,30 +251,42 @@ print("domain changed: " + domain); if (domain !== currentDomain) { MyAvatar.restoreAnimation(); - var name = AddressManager.placename; + var name = location.placename; domainName = name.charAt(0).toUpperCase() + name.slice(1); + var doRequest = true; + if (name.length === 0 && location.href === "file:///~/serverless/tutorial.json") { + domainName = "Serveless Domain (Tutorial)"; + doRequest = false; + } var domainNameLeftMargin = getLeftMargin(domainNameTextID, domainName); var textProperties = { text: domainName, leftMargin: domainNameLeftMargin }; - var url = Account.metaverseServerURL + '/api/v1/places/' + domain; - request({ - uri: url - }, function(error, data) { - if (data.status === "success") { - var domainInfo = data.data; - var domainDescriptionText = domainInfo.place.description; - print("domainText: " + domainDescriptionText); - var leftMargin = getLeftMargin(domainDescription, domainDescriptionText); - var domainDescriptionProperties = { - text: domainDescriptionText, - leftMargin: leftMargin - }; - Overlays.editOverlay(domainDescription, domainDescriptionProperties); - } - }); + if (doRequest) { + var url = Account.metaverseServerURL + '/api/v1/places/' + domain; + request({ + uri: url + }, function(error, data) { + if (data.status === "success") { + var domainInfo = data.data; + var domainDescriptionText = domainInfo.place.description; + print("domainText: " + domainDescriptionText); + var leftMargin = getLeftMargin(domainDescription, domainDescriptionText); + var domainDescriptionProperties = { + text: domainDescriptionText, + leftMargin: leftMargin + }; + Overlays.editOverlay(domainDescription, domainDescriptionProperties); + } + }); + } else { + var domainDescriptionProperties = { + text: "" + }; + Overlays.editOverlay(domainDescription, domainDescriptionProperties); + } var randomIndex = Math.floor(Math.random() * userTips.length); var tip = userTips[randomIndex]; @@ -320,8 +334,6 @@ visible: !physicsEnabled }; - // Menu.setIsOptionChecked("Show Overlays", physicsEnabled); - if (!HMD.active) { MyAvatar.headOrientation = Quat.multiply(Quat.cancelOutRollAndPitch(MyAvatar.headOrientation), Quat.fromPitchYawRollDegrees(-3.0, 0, 0)); } @@ -343,7 +355,9 @@ resetValues(); - Camera.mode = "first person"; + if (physicsEnabled) { + Camera.mode = previousCameraMode; + } } @@ -358,11 +372,6 @@ Overlays.editOverlay(anchorOverlay, { localPosition: localPosition }); } - - Window.interstitialStatusChanged.connect(function(interstitialMode) { - print("------> insterstitial mode changed " + interstitialMode + " <------"); - }); - function update() { var physicsEnabled = Window.isPhysicsEnabled(); var thisInterval = Date.now(); @@ -372,10 +381,13 @@ var domainLoadingProgressPercentage = Window.domainLoadingProgress(); var progress = MAX_X_SIZE * domainLoadingProgressPercentage; - print(progress); - //if (progress >= target) { + if (progress >= target) { target = progress; - //} + } + + if ((physicsEnabled && (currentProgress < MAX_X_SIZE))) { + target = MAX_X_SIZE; + } currentProgress = lerp(currentProgress, target, 0.2); var properties = { @@ -393,6 +405,7 @@ timer = null; return; } + timer = Script.setTimeout(update, BASIC_TIMER_INTERVAL_MS); } @@ -400,7 +413,6 @@ location.hostChanged.connect(domainChanged); location.lookupResultsFinished.connect(function() { Script.setTimeout(function() { - print("location connected: " + location.isConnected); connectionToDomainFailed = !location.isConnected; }, 1200); }); From 4b7ca76ebdecd76950acb7b2f0daecc174a397bd Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Thu, 30 Aug 2018 14:15:57 -0700 Subject: [PATCH 173/545] Create correct folder. --- libraries/shared/src/shared/FileUtils.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libraries/shared/src/shared/FileUtils.cpp b/libraries/shared/src/shared/FileUtils.cpp index 9bdd65bf11..0709a53602 100644 --- a/libraries/shared/src/shared/FileUtils.cpp +++ b/libraries/shared/src/shared/FileUtils.cpp @@ -156,10 +156,12 @@ bool FileUtils::canCreateFile(const QString& fullPath) { qDebug(shared) << "unable to overwrite file '" << fullPath << "'"; return false; } - QDir dir(fileInfo.absolutePath()); + + QString absolutePath = fileInfo.absolutePath(); + QDir dir(absolutePath); if (!dir.exists()) { - if (!dir.mkpath(fullPath)) { - qDebug(shared) << "unable to create dir '" << dir.absolutePath() << "'"; + if (!dir.mkpath(absolutePath)) { + qDebug(shared) << "unable to create dir '" << absolutePath << "'"; return false; } } From 03ede9371e1a070700952e4c504c445f1a51022a Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Thu, 30 Aug 2018 14:26:39 -0700 Subject: [PATCH 174/545] cleaning code --- interface/src/octree/SafeLanding.cpp | 2 -- interface/src/scripting/WindowScriptingInterface.cpp | 3 --- interface/src/scripting/WindowScriptingInterface.h | 3 --- 3 files changed, 8 deletions(-) diff --git a/interface/src/octree/SafeLanding.cpp b/interface/src/octree/SafeLanding.cpp index 8d36b3fcb0..6b7a0f582c 100644 --- a/interface/src/octree/SafeLanding.cpp +++ b/interface/src/octree/SafeLanding.cpp @@ -175,7 +175,6 @@ bool SafeLanding::entitiesRenderReady() { for (auto entityMapIter = _trackedEntitiesRenderStatus.begin(); entityMapIter != _trackedEntitiesRenderStatus.end(); ++entityMapIter) { auto entity = entityMapIter->second; bool visuallyReady = entity->isVisuallyReady(); - qDebug() << "is entityType: " << EntityTypes::getEntityTypeName(entity->getType()) << " " << visuallyReady << " " << entityMapIter->first; if (visuallyReady || !entityTree->renderableForEntityId(entityMapIter->first)) { entityMapIter = _trackedEntitiesRenderStatus.erase(entityMapIter); if (entityMapIter == _trackedEntitiesRenderStatus.end()) { @@ -185,7 +184,6 @@ bool SafeLanding::entitiesRenderReady() { entity->requestRenderUpdate(); } } - qDebug() << "list size: -> " << _trackedEntitiesRenderStatus.size(); return _trackedEntitiesRenderStatus.empty(); } diff --git a/interface/src/scripting/WindowScriptingInterface.cpp b/interface/src/scripting/WindowScriptingInterface.cpp index b4c1563795..9e13e2affb 100644 --- a/interface/src/scripting/WindowScriptingInterface.cpp +++ b/interface/src/scripting/WindowScriptingInterface.cpp @@ -53,9 +53,6 @@ WindowScriptingInterface::WindowScriptingInterface() { }); connect(qApp->getWindow(), &MainWindow::windowGeometryChanged, this, &WindowScriptingInterface::onWindowGeometryChanged); - connect(qApp, &Application::interstitialModeChanged, [this] (bool interstitialStatus) { - emit interstitialStatusChanged(interstitialStatus); - }); } WindowScriptingInterface::~WindowScriptingInterface() { diff --git a/interface/src/scripting/WindowScriptingInterface.h b/interface/src/scripting/WindowScriptingInterface.h index 3dcd8cfeed..626d142785 100644 --- a/interface/src/scripting/WindowScriptingInterface.h +++ b/interface/src/scripting/WindowScriptingInterface.h @@ -744,9 +744,6 @@ signals: */ void geometryChanged(QRect geometry); - - void interstitialStatusChanged(bool intersititalMode); - private: QString getPreviousBrowseLocation() const; void setPreviousBrowseLocation(const QString& location); From daf81bbcb8cb963ea5b020e0a70bf7640f7ca762 Mon Sep 17 00:00:00 2001 From: Alexander Ivash Date: Fri, 31 Aug 2018 00:29:06 +0300 Subject: [PATCH 175/545] FB17982 Avatar App reloads existing selected bookmark on app relaunch --- interface/resources/qml/hifi/AvatarApp.qml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/interface/resources/qml/hifi/AvatarApp.qml b/interface/resources/qml/hifi/AvatarApp.qml index d8eae311d8..0c950a49d8 100644 --- a/interface/resources/qml/hifi/AvatarApp.qml +++ b/interface/resources/qml/hifi/AvatarApp.qml @@ -175,7 +175,14 @@ Rectangle { displayNameInput.text = getAvatarsData.displayName; currentAvatarSettings = getAvatarsData.currentAvatarSettings; - updateCurrentAvatarInBookmarks(currentAvatar); + var bookmarkAvatarIndex = allAvatars.findAvatarIndexByValue(currentAvatar); + if (bookmarkAvatarIndex === -1) { + currentAvatar.name = ''; + } else { + currentAvatar.name = allAvatars.get(bookmarkAvatarIndex).name; + allAvatars.move(bookmarkAvatarIndex, 0, 1); + } + view.setPage(0); } else if (message.method === 'updateAvatarInBookmarks') { updateCurrentAvatarInBookmarks(currentAvatar); } else if (message.method === 'selectAvatarEntity') { From 0f6fdef9284c95bc8a68e031bca7796618ec519d Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Thu, 30 Aug 2018 15:06:05 -0700 Subject: [PATCH 176/545] Fixed compilation error (within #ifdef) --- libraries/fbx/src/OBJReader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/fbx/src/OBJReader.cpp b/libraries/fbx/src/OBJReader.cpp index 501fb72130..c46a1e234c 100644 --- a/libraries/fbx/src/OBJReader.cpp +++ b/libraries/fbx/src/OBJReader.cpp @@ -273,7 +273,7 @@ void OBJReader::parseMaterialLibrary(QIODevice* device) { " diffuse texture:" << currentMaterial.diffuseTextureFilename << " specular texture:" << currentMaterial.specularTextureFilename << " emissive texture:" << currentMaterial.emissiveTextureFilename << - " bump texture:" << currentMaterial.bumpTextureFilename; + " bump texture:" << currentMaterial.bumpTextureFilename << " opacity texture:" << currentMaterial.opacityTextureFilename; #endif return; From cb1855b0d7163e7170bb62185d68db3b8a5a285a Mon Sep 17 00:00:00 2001 From: Alexander Ivash Date: Wed, 29 Aug 2018 22:34:35 +0300 Subject: [PATCH 177/545] filter out left/right hands from joints list in avatarapp should fix: FB17884 - Wearable disappears when added to some joints FB17885 - Changing werable joint moves the model and detaches from avatar body --- interface/resources/qml/hifi/AvatarApp.qml | 2 +- .../qml/hifi/avatarapp/AdjustWearables.qml | 30 +++++++++++++++---- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/interface/resources/qml/hifi/AvatarApp.qml b/interface/resources/qml/hifi/AvatarApp.qml index d8eae311d8..0cbf0637f8 100644 --- a/interface/resources/qml/hifi/AvatarApp.qml +++ b/interface/resources/qml/hifi/AvatarApp.qml @@ -46,7 +46,7 @@ Rectangle { } } - property var jointNames; + property var jointNames: [] property var currentAvatarSettings; function fetchAvatarModelName(marketId, avatar) { diff --git a/interface/resources/qml/hifi/avatarapp/AdjustWearables.qml b/interface/resources/qml/hifi/avatarapp/AdjustWearables.qml index e80dab60c2..b63720408e 100644 --- a/interface/resources/qml/hifi/avatarapp/AdjustWearables.qml +++ b/interface/resources/qml/hifi/avatarapp/AdjustWearables.qml @@ -25,7 +25,17 @@ Rectangle { modified = false; } - property var jointNames; + property var jointNames: [] + onJointNamesChanged: { + jointsModel.clear(); + for (var i = 0; i < jointNames.length; ++i) { + var jointName = jointNames[i]; + if(jointName !== 'LeftHand' && jointName !== 'RightHand') { + jointsModel.append({'text' : jointName, 'jointIndex' : i}); + } + } + } + property string avatarName: '' property var wearablesModel; @@ -268,20 +278,30 @@ Rectangle { anchors.right: parent.right enabled: getCurrentWearable() !== null && !isSoft.checked comboBox.displayText: isSoft.checked ? 'Hips' : comboBox.currentText + comboBox.textRole: "text" - model: jointNames + model: ListModel { + id: jointsModel + } property bool notify: false function set(jointIndex) { notify = false; - currentIndex = jointIndex; + for(var i = 0; i < jointsModel.count; ++i) { + if(jointsModel.get(i).jointIndex === jointIndex) { + currentIndex = i; + break; + } + } notify = true; } function notifyJointChanged() { modified = true; + var jointIndex = jointsModel.get(jointsCombobox.currentIndex).jointIndex; + var properties = { - parentJointIndex: currentIndex, + parentJointIndex: jointIndex, localPosition: { x: positionVector.xvalue, y: positionVector.yvalue, @@ -294,7 +314,7 @@ Rectangle { } }; - wearableUpdated(getCurrentWearable().id, wearablesCombobox.currentIndex, properties); + wearableUpdated(getCurrentWearable().id, jointIndex, properties); } onCurrentIndexChanged: { From 07739453c586eab4c42ed16e42e92f35e07db367 Mon Sep 17 00:00:00 2001 From: Alexander Ivash Date: Thu, 30 Aug 2018 07:44:55 +0300 Subject: [PATCH 178/545] coding standards --- interface/resources/qml/hifi/avatarapp/AdjustWearables.qml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/resources/qml/hifi/avatarapp/AdjustWearables.qml b/interface/resources/qml/hifi/avatarapp/AdjustWearables.qml index b63720408e..5bf867a331 100644 --- a/interface/resources/qml/hifi/avatarapp/AdjustWearables.qml +++ b/interface/resources/qml/hifi/avatarapp/AdjustWearables.qml @@ -30,7 +30,7 @@ Rectangle { jointsModel.clear(); for (var i = 0; i < jointNames.length; ++i) { var jointName = jointNames[i]; - if(jointName !== 'LeftHand' && jointName !== 'RightHand') { + if (jointName !== 'LeftHand' && jointName !== 'RightHand') { jointsModel.append({'text' : jointName, 'jointIndex' : i}); } } @@ -287,8 +287,8 @@ Rectangle { function set(jointIndex) { notify = false; - for(var i = 0; i < jointsModel.count; ++i) { - if(jointsModel.get(i).jointIndex === jointIndex) { + for (var i = 0; i < jointsModel.count; ++i) { + if (jointsModel.get(i).jointIndex === jointIndex) { currentIndex = i; break; } From 5f08ed5027a8904242a47b17e994ab4f309e3930 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 30 Aug 2018 15:13:52 -0700 Subject: [PATCH 179/545] misc perf improvements --- .../src/avatars/AvatarMixerSlave.cpp | 6 +- interface/src/avatar/AvatarManager.cpp | 23 +++----- interface/src/avatar/OtherAvatar.cpp | 9 ++- .../src/controllers/UserInputMapper.cpp | 6 +- .../src/EntityTreeRenderer.cpp | 9 ++- .../graphics/src/graphics/BufferViewHelpers.h | 5 +- libraries/shared/src/AABox.cpp | 56 ++++--------------- libraries/shared/src/AABox.h | 17 +++++- libraries/shared/src/GLMHelpers.h | 8 +++ libraries/shared/src/PrioritySortUtil.h | 15 +++-- tests/shared/src/AACubeTests.cpp | 2 +- tests/shared/src/GLMHelpersTests.cpp | 36 ++++++++++++ tests/shared/src/GLMHelpersTests.h | 1 + 13 files changed, 108 insertions(+), 85 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index f347ff1f10..59c6db5dc4 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -429,9 +429,9 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) int remainingAvatars = (int)sortedAvatars.size(); auto traitsPacketList = NLPacketList::create(PacketType::BulkAvatarTraits, QByteArray(), true, true); - while (!sortedAvatars.empty()) { - const auto avatarData = sortedAvatars.top().getAvatar(); - sortedAvatars.pop(); + const auto& sortedAvatarVector = sortedAvatars.getSortedVector(); + for (const auto& sortedAvatar : sortedAvatarVector) { + const auto& avatarData = sortedAvatar.getAvatar(); remainingAvatars--; auto otherNode = avatarDataToNodes[avatarData]; diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 9a7d8ef0c8..af9d9ad6b1 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -206,6 +206,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { } ++itr; } + const auto& sortedAvatarVector = sortedAvatars.getSortedVector(); // process in sorted order uint64_t startTime = usecTimestampNow(); @@ -216,8 +217,8 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { render::Transaction renderTransaction; workload::Transaction workloadTransaction; - while (!sortedAvatars.empty()) { - const SortableAvatar& sortData = sortedAvatars.top(); + for (auto it = sortedAvatarVector.begin(); it != sortedAvatarVector.end(); ++it) { + const SortableAvatar& sortData = *it; const auto avatar = std::static_pointer_cast(sortData.getAvatar()); // TODO: to help us scale to more avatars it would be nice to not have to poll orb state here @@ -231,7 +232,6 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { bool ignoring = DependencyManager::get()->isPersonalMutingNode(avatar->getID()); if (ignoring) { - sortedAvatars.pop(); continue; } @@ -260,26 +260,17 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { // --> some avatar velocity measurements may be a little off // no time to simulate, but we take the time to count how many were tragically missed - bool inView = sortData.getPriority() > OUT_OF_VIEW_THRESHOLD; - if (!inView) { - break; - } - if (inView && avatar->hasNewJointData()) { - numAVatarsNotUpdated++; - } - sortedAvatars.pop(); - while (inView && !sortedAvatars.empty()) { - const SortableAvatar& newSortData = sortedAvatars.top(); + while (it != sortedAvatarVector.end()) { + const SortableAvatar& newSortData = *it; const auto newAvatar = std::static_pointer_cast(newSortData.getAvatar()); - inView = newSortData.getPriority() > OUT_OF_VIEW_THRESHOLD; + bool inView = newSortData.getPriority() > OUT_OF_VIEW_THRESHOLD; if (inView && newAvatar->hasNewJointData()) { numAVatarsNotUpdated++; } - sortedAvatars.pop(); + ++it; } break; } - sortedAvatars.pop(); } if (_shouldRender) { diff --git a/interface/src/avatar/OtherAvatar.cpp b/interface/src/avatar/OtherAvatar.cpp index 29ad5aed91..a0fa496c4c 100644 --- a/interface/src/avatar/OtherAvatar.cpp +++ b/interface/src/avatar/OtherAvatar.cpp @@ -29,20 +29,23 @@ OtherAvatar::~OtherAvatar() { } void OtherAvatar::removeOrb() { - if (qApp->getOverlays().isAddedOverlay(_otherAvatarOrbMeshPlaceholderID)) { + if (!_otherAvatarOrbMeshPlaceholderID.isNull()) { qApp->getOverlays().deleteOverlay(_otherAvatarOrbMeshPlaceholderID); + _otherAvatarOrbMeshPlaceholderID = UNKNOWN_OVERLAY_ID; } } void OtherAvatar::updateOrbPosition() { if (_otherAvatarOrbMeshPlaceholder != nullptr) { _otherAvatarOrbMeshPlaceholder->setWorldPosition(getHead()->getPosition()); + if (_otherAvatarOrbMeshPlaceholderID.isNull()) { + _otherAvatarOrbMeshPlaceholderID = qApp->getOverlays().addOverlay(_otherAvatarOrbMeshPlaceholder); + } } } void OtherAvatar::createOrb() { - if (_otherAvatarOrbMeshPlaceholderID == UNKNOWN_OVERLAY_ID || - !qApp->getOverlays().isAddedOverlay(_otherAvatarOrbMeshPlaceholderID)) { + if (_otherAvatarOrbMeshPlaceholderID.isNull()) { _otherAvatarOrbMeshPlaceholder = std::make_shared(); _otherAvatarOrbMeshPlaceholder->setAlpha(1.0f); _otherAvatarOrbMeshPlaceholder->setColor({ 0xFF, 0x00, 0xFF }); diff --git a/libraries/controllers/src/controllers/UserInputMapper.cpp b/libraries/controllers/src/controllers/UserInputMapper.cpp index 371deec7d5..307064c073 100755 --- a/libraries/controllers/src/controllers/UserInputMapper.cpp +++ b/libraries/controllers/src/controllers/UserInputMapper.cpp @@ -527,8 +527,8 @@ bool UserInputMapper::applyRoute(const Route::Pointer& route, bool force) { } // If the source hasn't been written yet, defer processing of this route - auto source = route->source; - auto sourceInput = source->getInput(); + auto& source = route->source; + auto& sourceInput = source->getInput(); if (sourceInput.device == STANDARD_DEVICE && !force && source->writeable()) { if (debugRoutes && route->debug) { qCDebug(controllers) << "Source not yet written, deferring"; @@ -559,7 +559,7 @@ bool UserInputMapper::applyRoute(const Route::Pointer& route, bool force) { return true; } - auto destination = route->destination; + auto& destination = route->destination; // THis could happen if the route destination failed to create // FIXME: Maybe do not create the route if the destination failed and avoid this case ? if (!destination) { diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index c3c4095251..a363093083 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -405,11 +405,14 @@ void EntityTreeRenderer::updateChangedEntities(const render::ScenePointer& scene // process the sorted renderables size_t numSorted = sortedRenderables.size(); - while (!sortedRenderables.empty() && usecTimestampNow() < expiry) { - const auto renderable = sortedRenderables.top().getRenderer(); + const auto& sortedRenderablesVector = sortedRenderables.getSortedVector(); + for (const auto& sortedRenderable : sortedRenderablesVector) { + if (usecTimestampNow() > expiry) { + break; + } + const auto& renderable = sortedRenderable.getRenderer(); renderable->updateInScene(scene, transaction); _renderablesToUpdate.erase(renderable->getEntity()->getID()); - sortedRenderables.pop(); } // compute average per-renderable update cost diff --git a/libraries/graphics/src/graphics/BufferViewHelpers.h b/libraries/graphics/src/graphics/BufferViewHelpers.h index a9707c3128..7c37c75163 100644 --- a/libraries/graphics/src/graphics/BufferViewHelpers.h +++ b/libraries/graphics/src/graphics/BufferViewHelpers.h @@ -13,6 +13,7 @@ #include #include "GpuHelpers.h" +#include "GLMHelpers.h" namespace graphics { class Mesh; @@ -55,8 +56,8 @@ namespace buffer_helpers { tangent = glm::clamp(tangent, -1.0f, 1.0f); normal *= 511.0f; tangent *= 511.0f; - normal = glm::round(normal); - tangent = glm::round(tangent); + normal = fastRoundf(normal); + tangent = fastRoundf(tangent); glm::detail::i10i10i10i2 normalStruct; glm::detail::i10i10i10i2 tangentStruct; diff --git a/libraries/shared/src/AABox.cpp b/libraries/shared/src/AABox.cpp index b4384c494f..e537c3e56a 100644 --- a/libraries/shared/src/AABox.cpp +++ b/libraries/shared/src/AABox.cpp @@ -79,33 +79,23 @@ void AABox::setBox(const glm::vec3& corner, const glm::vec3& scale) { glm::vec3 AABox::getFarthestVertex(const glm::vec3& normal) const { glm::vec3 result = _corner; - if (normal.x > 0.0f) { - result.x += _scale.x; - } - if (normal.y > 0.0f) { - result.y += _scale.y; - } - if (normal.z > 0.0f) { - result.z += _scale.z; - } + float blend = (float)(normal.x > 0.0f); + result.x += blend * _scale.x + (1.0f - blend) * 0.0f; + blend = (float)(normal.y > 0.0f); + result.y += blend * _scale.y + (1.0f - blend) * 0.0f; + blend = (float)(normal.z > 0.0f); + result.z += blend * _scale.z + (1.0f - blend) * 0.0f; return result; } glm::vec3 AABox::getNearestVertex(const glm::vec3& normal) const { glm::vec3 result = _corner; - - if (normal.x < 0.0f) { - result.x += _scale.x; - } - - if (normal.y < 0.0f) { - result.y += _scale.y; - } - - if (normal.z < 0.0f) { - result.z += _scale.z; - } - + float blend = (float)(normal.x < 0.0f); + result.x += blend * _scale.x + (1.0f - blend) * 0.0f; + blend = (float)(normal.y < 0.0f); + result.y += blend * _scale.y + (1.0f - blend) * 0.0f; + blend = (float)(normal.z < 0.0f); + result.z += blend * _scale.z + (1.0f - blend) * 0.0f; return result; } @@ -459,28 +449,6 @@ AABox AABox::clamp(float min, float max) const { return AABox(clampedCorner, clampedScale); } -AABox& AABox::operator += (const glm::vec3& point) { - - if (isInvalid()) { - _corner = glm::min(_corner, point); - } else { - glm::vec3 maximum(_corner + _scale); - _corner = glm::min(_corner, point); - maximum = glm::max(maximum, point); - _scale = maximum - _corner; - } - - return (*this); -} - -AABox& AABox::operator += (const AABox& box) { - if (!box.isInvalid()) { - (*this) += box._corner; - (*this) += box.calcTopFarLeft(); - } - return (*this); -} - void AABox::embiggen(float scale) { _corner += scale * (-0.5f * _scale); _scale *= scale; diff --git a/libraries/shared/src/AABox.h b/libraries/shared/src/AABox.h index daad01d7c7..a56615c40e 100644 --- a/libraries/shared/src/AABox.h +++ b/libraries/shared/src/AABox.h @@ -85,8 +85,21 @@ public: AABox clamp(const glm::vec3& min, const glm::vec3& max) const; AABox clamp(float min, float max) const; - AABox& operator += (const glm::vec3& point); - AABox& operator += (const AABox& box); + inline AABox& operator+=(const glm::vec3& point) { + float blend = (float)isInvalid(); + glm::vec3 maximumScale(glm::max(_scale, point - _corner)); + _corner = glm::min(_corner, point); + _scale = blend * _scale + (1.0f - blend) * maximumScale; + return (*this); + } + + inline AABox& operator+=(const AABox& box) { + if (!box.isInvalid()) { + (*this) += box._corner; + (*this) += box.calcTopFarLeft(); + } + return (*this); + } // Translate the AABox just moving the corner void translate(const glm::vec3& translation) { _corner += translation; } diff --git a/libraries/shared/src/GLMHelpers.h b/libraries/shared/src/GLMHelpers.h index 7e6ef4cb28..619f8172d5 100644 --- a/libraries/shared/src/GLMHelpers.h +++ b/libraries/shared/src/GLMHelpers.h @@ -316,4 +316,12 @@ inline void glm_mat4u_mul(const glm::mat4& m1, const glm::mat4& m2, glm::mat4& r #endif } +inline glm::vec3 fastRoundf(const glm::vec3& vec) { +#if GLM_ARCH & GLM_ARCH_SSE2_BIT + return glm::vec3(_mm_cvt_ss2si(_mm_set_ss(vec.x)), _mm_cvt_ss2si(_mm_set_ss(vec.y)), _mm_cvt_ss2si(_mm_set_ss(vec.z))); +#else + return glm::round(vec); +#endif +} + #endif // hifi_GLMHelpers_h diff --git a/libraries/shared/src/PrioritySortUtil.h b/libraries/shared/src/PrioritySortUtil.h index 34ec074d45..e0137b3d8c 100644 --- a/libraries/shared/src/PrioritySortUtil.h +++ b/libraries/shared/src/PrioritySortUtil.h @@ -12,7 +12,6 @@ #define hifi_PrioritySortUtil_h #include -#include #include "NumericalConstants.h" #include "shared/ConicalViewFrustum.h" @@ -75,7 +74,6 @@ namespace PrioritySortUtil { void setPriority(float priority) { _priority = priority; } float getPriority() const { return _priority; } - bool operator<(const Sortable& other) const { return _priority < other._priority; } private: float _priority { 0.0f }; }; @@ -97,14 +95,15 @@ namespace PrioritySortUtil { _ageWeight = ageWeight; } - size_t size() const { return _queue.size(); } + size_t size() const { return _vector.size(); } void push(T thing) { thing.setPriority(computePriority(thing)); - _queue.push(thing); + _vector.push_back(thing); + } + const std::vector& getSortedVector() { + std::sort(_vector.begin(), _vector.end(), [](const T& left, const T& right) { return left.getPriority() > right.getPriority(); }); + return _vector; } - const T& top() const { return _queue.top(); } - void pop() { return _queue.pop(); } - bool empty() const { return _queue.empty(); } private: @@ -153,7 +152,7 @@ namespace PrioritySortUtil { } ConicalViewFrustums _views; - std::priority_queue _queue; + std::vector _vector; float _angularWeight { DEFAULT_ANGULAR_COEF }; float _centerWeight { DEFAULT_CENTER_COEF }; float _ageWeight { DEFAULT_AGE_COEF }; diff --git a/tests/shared/src/AACubeTests.cpp b/tests/shared/src/AACubeTests.cpp index 95a4d7f9f0..c3c8e3e6f7 100644 --- a/tests/shared/src/AACubeTests.cpp +++ b/tests/shared/src/AACubeTests.cpp @@ -173,7 +173,7 @@ void AACubeTests::rayVsParabolaPerformance() { glm::vec3 normal; auto start = std::chrono::high_resolution_clock::now(); for (auto& cube : cubes) { - if (cube.findRayIntersection(origin, direction, distance, face, normal)) { + if (cube.findRayIntersection(origin, direction, 1.0f / direction, distance, face, normal)) { numRayHits++; } } diff --git a/tests/shared/src/GLMHelpersTests.cpp b/tests/shared/src/GLMHelpersTests.cpp index 93c4735a6d..669bbb8e43 100644 --- a/tests/shared/src/GLMHelpersTests.cpp +++ b/tests/shared/src/GLMHelpersTests.cpp @@ -214,3 +214,39 @@ void GLMHelpersTests::testGenerateBasisVectors() { QCOMPARE_WITH_ABS_ERROR(w, z, EPSILON); } } + +void GLMHelpersTests::roundPerf() { + const int NUM_VECS = 1000000; + const float MAX_VEC = 500.0f; + std::vector vecs; + vecs.reserve(NUM_VECS); + for (int i = 0; i < NUM_VECS; i++) { + vecs.emplace_back(randFloatInRange(-MAX_VEC, MAX_VEC), randFloatInRange(-MAX_VEC, MAX_VEC), randFloatInRange(-MAX_VEC, MAX_VEC)); + } + std::vector vecs2 = vecs; + std::vector originalVecs = vecs; + + auto start = std::chrono::high_resolution_clock::now(); + for (auto& vec : vecs) { + vec = glm::round(vec); + } + + auto glmTime = std::chrono::high_resolution_clock::now() - start; + start = std::chrono::high_resolution_clock::now(); + for (auto& vec : vecs2) { + vec = fastRoundf(vec); + } + auto manualTime = std::chrono::high_resolution_clock::now() - start; + + bool identical = true; + for (int i = 0; i < vecs.size(); i++) { + identical &= vecs[i] == vecs2[i]; + if (vecs[i] != vecs2[i]) { + qDebug() << "glm: " << vecs[i].x << vecs[i].y << vecs[i].z << ", manual: " << vecs2[i].x << vecs2[i].y << vecs2[i].z; + qDebug() << "original: " << originalVecs[i].x << originalVecs[i].y << originalVecs[i].z; + break; + } + } + + qDebug() << "ratio: " << (float)glmTime.count() / (float)manualTime.count() << ", identical: " << identical; +} \ No newline at end of file diff --git a/tests/shared/src/GLMHelpersTests.h b/tests/shared/src/GLMHelpersTests.h index 030f2d477f..4d9bd0bb60 100644 --- a/tests/shared/src/GLMHelpersTests.h +++ b/tests/shared/src/GLMHelpersTests.h @@ -22,6 +22,7 @@ private slots: void testSixByteOrientationCompression(); void testSimd(); void testGenerateBasisVectors(); + void roundPerf(); }; float getErrorDifference(const float& a, const float& b); From 33db1394e6dde359fda68a131354f7a56066c42e Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Thu, 30 Aug 2018 17:12:42 -0700 Subject: [PATCH 180/545] Use system_clock in usecTimestampNow for cross-platform goodness --- libraries/shared/src/SharedUtil.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/shared/src/SharedUtil.cpp b/libraries/shared/src/SharedUtil.cpp index a36bdb061e..6c79a23c20 100644 --- a/libraries/shared/src/SharedUtil.cpp +++ b/libraries/shared/src/SharedUtil.cpp @@ -134,7 +134,8 @@ void usecTimestampNowForceClockSkew(qint64 clockSkew) { quint64 usecTimestampNow(bool wantDebug) { using namespace std::chrono; - return duration_cast(high_resolution_clock::now().time_since_epoch()).count(); + static const auto unixEpoch = system_clock::from_time_t(0); + return duration_cast(system_clock::now() - unixEpoch).count(); #if 0 std::call_once(usecTimestampNowIsInitialized, [&] { TIME_REFERENCE = QDateTime::currentMSecsSinceEpoch() * USECS_PER_MSEC; // ms to usec From 07b24b47688763d1cab3979264713837ee54b38c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 30 Aug 2018 17:22:27 -0700 Subject: [PATCH 181/545] send kill packet to ignored node for ignorer --- assignment-client/src/avatars/AvatarMixer.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index edbba20dc7..0289a8aa3f 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -654,6 +654,12 @@ void AvatarMixer::handleNodeIgnoreRequestPacket(QSharedPointer if (addToIgnore) { senderNode->addIgnoredNode(ignoredUUID); + + // send a reliable kill packet to remove the sending avatar for the ignored avatar + auto killPacket = NLPacket::create(PacketType::KillAvatar, NUM_BYTES_RFC4122_UUID + sizeof(KillAvatarReason), true); + killPacket->write(senderNode->getUUID().toRfc4122()); + killPacket->writePrimitive(KillAvatarReason::AvatarDisconnected); + nodeList->sendPacket(std::move(killPacket), *ignoredNode); } else { senderNode->removeIgnoredNode(ignoredUUID); } From 5f43f5b27626d8120b67134bca2decb3d91db58a Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Thu, 30 Aug 2018 17:40:13 -0700 Subject: [PATCH 182/545] adding different method for handling redirect --- interface/src/Application.cpp | 32 ++++----------------- interface/src/Application.h | 2 +- libraries/networking/src/AddressManager.cpp | 4 ++- libraries/networking/src/DomainHandler.cpp | 14 +++++++++ libraries/networking/src/DomainHandler.h | 6 ++++ 5 files changed, 29 insertions(+), 29 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 348d1d5690..1041ab64ca 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1197,11 +1197,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo getOverlays().deleteOverlay(getTabletHomeButtonID()); getOverlays().deleteOverlay(getTabletFrameID()); }); -#if defined(Q_OS_ANDROID) connect(&domainHandler, &DomainHandler::domainConnectionRefused, this, &Application::domainConnectionRefused); -#else - connect(&domainHandler, &DomainHandler::domainConnectionRefused, this, &Application::domainConnectionRedirect); -#endif + + &domainHandler.setErrorDomainURL(QUrl(REDIRECT_HIFI_ADDRESS)); // We could clear ATP assets only when changing domains, but it's possible that the domain you are connected // to has gone down and switched to a new content set, so when you reconnect the cached ATP assets will no longer be valid. @@ -2350,31 +2348,11 @@ void Application::domainConnectionRefused(const QString& reasonMessage, int reas } } -void Application::domainConnectionRedirect(const QString& reasonMessage, int reasonCodeInt, const QString& extraInfo) { - DomainHandler::ConnectionRefusedReason reasonCode = static_cast(reasonCodeInt); +void Application::domainConnectionRedirect() { auto addressManager = DependencyManager::get(); - if (reasonCode == DomainHandler::ConnectionRefusedReason::TooManyUsers && !extraInfo.isEmpty()) { - addressManager->handleLookupString(extraInfo); - return; - } - - switch (reasonCode) { - case DomainHandler::ConnectionRefusedReason::ProtocolMismatch: - case DomainHandler::ConnectionRefusedReason::TooManyUsers: - case DomainHandler::ConnectionRefusedReason::Unknown: { - QString message = "Unable to connect to the location you are visiting.\n"; - message += reasonMessage; - //OffscreenUi::asyncWarning("", message); - addressManager->handleLookupString(REDIRECT_HIFI_ADDRESS); - getMyAvatar()->setWorldVelocity(glm::vec3(0.0f)); - // in (w, x, y, z) component-structure for the constructor - break; - } - default: - // nothing to do. - break; - } + addressManager->handleLookupString(REDIRECT_HIFI_ADDRESS); + getMyAvatar()->setWorldVelocity(glm::vec3(0.0f)); } diff --git a/interface/src/Application.h b/interface/src/Application.h index 61548f203b..e38b5a3919 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -474,7 +474,7 @@ private slots: void updateDisplayMode(); void setDisplayPlugin(DisplayPluginPointer newPlugin); void domainConnectionRefused(const QString& reasonMessage, int reason, const QString& extraInfo); - void domainConnectionRedirect(const QString& reasonMessage, int reason, const QString& extraInfo); + void domainConnectionRedirect(); void addAssetToWorldCheckModelSize(); diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 732a2d7963..01db8dfd79 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -319,7 +319,9 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) { // lookupUrl.scheme() == URL_SCHEME_HTTPS || _previousLookup.clear(); _shareablePlaceName.clear(); - setDomainInfo(lookupUrl, trigger); + if (lookupUrl.toString() != REDIRECT_HIFI_ADDRESS) { + setDomainInfo(lookupUrl, trigger); + } emit lookupResultsFinished(); QString path = DOMAIN_SPAWNING_POINT; diff --git a/libraries/networking/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp index 39c8b5b1a1..827232129f 100644 --- a/libraries/networking/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -128,6 +128,10 @@ void DomainHandler::hardReset() { _pendingPath.clear(); } +void DomainHandler::setErrorDomainURL(const QUrl& url) { + return; +} + void DomainHandler::setSockAddr(const HifiSockAddr& sockAddr, const QString& hostname) { if (_sockAddr != sockAddr) { // we should reset on a sockAddr change @@ -451,7 +455,17 @@ void DomainHandler::processDomainServerConnectionDeniedPacket(QSharedPointer(); diff --git a/libraries/networking/src/DomainHandler.h b/libraries/networking/src/DomainHandler.h index a428110db6..473cac9133 100644 --- a/libraries/networking/src/DomainHandler.h +++ b/libraries/networking/src/DomainHandler.h @@ -50,6 +50,9 @@ public: QString getHostname() const { return _domainURL.host(); } + QUrl getErrorDomainURL(){ return _errorDomainURL; } + void setErrorDomainURL(const QUrl& url); + const QHostAddress& getIP() const { return _sockAddr.getAddress(); } void setIPToLocalhost() { _sockAddr.setAddress(QHostAddress(QHostAddress::LocalHost)); } @@ -179,6 +182,7 @@ signals: void settingsReceiveFail(); void domainConnectionRefused(QString reasonMessage, int reason, const QString& extraInfo); + void redirectToErrorDomainURL(); void limitOfSilentDomainCheckInsReached(); @@ -190,6 +194,7 @@ private: QUuid _uuid; Node::LocalID _localID; QUrl _domainURL; + QUrl _errorDomainURL; HifiSockAddr _sockAddr; QUuid _assignmentUUID; QUuid _connectionToken; @@ -198,6 +203,7 @@ private: HifiSockAddr _iceServerSockAddr; NetworkPeer _icePeer; bool _isConnected { false }; + bool _isInErrorState { false }; QJsonObject _settingsObject; QString _pendingPath; QTimer _settingsTimer; From 194903692ed5b7cc13e6b939a2bed89ea8c7ee26 Mon Sep 17 00:00:00 2001 From: sam gateau Date: Thu, 30 Aug 2018 18:09:11 -0700 Subject: [PATCH 183/545] clening up the code in LODmanager and the associated js/qml --- interface/src/LODManager.cpp | 498 ++++++++++----------- interface/src/LODManager.h | 157 +++---- interface/src/ui/PreferencesDialog.cpp | 48 -- libraries/render/src/render/Args.h | 10 +- libraries/render/src/render/CullTask.cpp | 2 +- scripts/developer/utilities/render/lod.qml | 13 +- 6 files changed, 317 insertions(+), 411 deletions(-) diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index 925d48f9cd..738c3dd9fb 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -19,27 +19,15 @@ #include "ui/DialogsManager.h" #include "InterfaceLogging.h" +const float LODManager::DEFAULT_DESKTOP_LOD_DOWN_FPS = LOD_OFFSET_FPS + LOD_DEFAULT_QUALITY_LEVEL * LOD_MAX_LIKELY_DESKTOP_FPS; +const float LODManager::DEFAULT_HMD_LOD_DOWN_FPS = LOD_OFFSET_FPS + LOD_DEFAULT_QUALITY_LEVEL * LOD_MAX_LIKELY_HMD_FPS; -Setting::Handle desktopLODDecreaseFPS("desktopLODDecreaseFPS", DEFAULT_DESKTOP_LOD_DOWN_FPS); -Setting::Handle hmdLODDecreaseFPS("hmdLODDecreaseFPS", DEFAULT_HMD_LOD_DOWN_FPS); +Setting::Handle desktopLODDecreaseFPS("desktopLODDecreaseFPS", LODManager::DEFAULT_DESKTOP_LOD_DOWN_FPS); +Setting::Handle hmdLODDecreaseFPS("hmdLODDecreaseFPS", LODManager::DEFAULT_HMD_LOD_DOWN_FPS); LODManager::LODManager() { } -float LODManager::getLODDecreaseFPS() const { - if (qApp->isHMDMode()) { - return getHMDLODDecreaseFPS(); - } - return getDesktopLODDecreaseFPS(); -} - -float LODManager::getLODIncreaseFPS() const { - if (qApp->isHMDMode()) { - return getHMDLODIncreaseFPS(); - } - return getDesktopLODIncreaseFPS(); -} - // We use a "time-weighted running average" of the maxRenderTime and compare it against min/max thresholds // to determine if we should adjust the level of detail (LOD). // @@ -55,8 +43,12 @@ const float LOD_ADJUST_RUNNING_AVG_TIMESCALE = 0.08f; // sec // multiples of the running average timescale: const uint64_t LOD_AUTO_ADJUST_PERIOD = 4 * (uint64_t)(LOD_ADJUST_RUNNING_AVG_TIMESCALE * (float)USECS_PER_MSEC); // usec -const float LOD_AUTO_ADJUST_DECREMENT_FACTOR = 0.8f; -const float LOD_AUTO_ADJUST_INCREMENT_FACTOR = 1.2f; +// batchTIme is always contained in presentTime. +// We favor using batchTime instead of presentTime as a representative value for rendering duration (on present thread) +// if batchTime + cushionTime < presentTime. +// since we are shooting for fps around 60, 90Hz, the ideal frames are around 10ms +// so we are picking a cushion time of 3ms +const float LOD_BATCH_TO_PRESENT_CUSHION_TIME = 10.0f; // msec void LODManager::setRenderTimes(float presentTime, float engineRunTime, float batchTime, float gpuTime) { _presentTime = presentTime; @@ -66,6 +58,7 @@ void LODManager::setRenderTimes(float presentTime, float engineRunTime, float ba } void LODManager::autoAdjustLOD(float realTimeDelta) { + // The "render time" is the worse of: // - engineRunTime: Time spent in the render thread in the engine producing the gpu::Frame N // - batchTime: Time spent in the present thread processing the batches of gpu::Frame N+1 @@ -73,50 +66,42 @@ void LODManager::autoAdjustLOD(float realTimeDelta) { // - gpuTime: Time spent in the GPU executing the gpu::Frame N + 2 // But Present time is in reality synched with the monitor/display refresh rate, it s always longer than batchTime. - // So if batchTime is fast enough relative to PResent Time we are using it, otherwise we are using presentTime. got it ? - auto presentTime = (_presentTime - _batchTime > 3.0f ? _batchTime + 3.0f : _presentTime); + // So if batchTime is fast enough relative to presentTime we are using it, otherwise we are using presentTime. got it ? + auto presentTime = (_presentTime > _batchTime + LOD_BATCH_TO_PRESENT_CUSHION_TIME ? _batchTime + LOD_BATCH_TO_PRESENT_CUSHION_TIME : _presentTime); float maxRenderTime = glm::max(glm::max(presentTime, _engineRunTime), _gpuTime); // compute time-weighted running average maxRenderTime // Note: we MUST clamp the blend to 1.0 for stability - float blend = (realTimeDelta < LOD_ADJUST_RUNNING_AVG_TIMESCALE) ? realTimeDelta / LOD_ADJUST_RUNNING_AVG_TIMESCALE : 1.0f; - _avgRenderTime = (1.0f - blend) * _avgRenderTime + blend * maxRenderTime; // msec + float nowBlend = (realTimeDelta < LOD_ADJUST_RUNNING_AVG_TIMESCALE) ? realTimeDelta / LOD_ADJUST_RUNNING_AVG_TIMESCALE : 1.0f; + _nowRenderTime = (1.0f - nowBlend) * _nowRenderTime + nowBlend * maxRenderTime; // msec float smoothBlend = (realTimeDelta < LOD_ADJUST_RUNNING_AVG_TIMESCALE * _smoothScale) ? realTimeDelta / (LOD_ADJUST_RUNNING_AVG_TIMESCALE * _smoothScale) : 1.0f; _smoothRenderTime = (1.0f - smoothBlend) * _smoothRenderTime + smoothBlend * maxRenderTime; // msec - - // _avgRenderTime = maxRenderTime; - if (!_automaticLODAdjust || _avgRenderTime == 0.0f) { + if (!_automaticLODAdjust || _nowRenderTime == 0.0f) { // early exit return; } - float oldOctreeSizeScale = _octreeSizeScale; - float oldSolidAngle = getLODAngleDeg(); + // Previous values for output + float oldOctreeSizeScale = getOctreeSizeScale(); + float oldLODAngle = getLODAngleDeg(); - float targetFPS = 0.5 * (getLODDecreaseFPS() + getLODIncreaseFPS()); - float targetPeriod = 1.0f / targetFPS; - - float currentFPS = (float)MSECS_PER_SECOND / _avgRenderTime; + // Target fps and current fps based on latest measurments + float targetFPS = getLODTargetFPS(); + float currentNowFPS = (float)MSECS_PER_SECOND / _nowRenderTime; float currentSmoothFPS = (float)MSECS_PER_SECOND / _smoothRenderTime; // Compute the Variance of the FPS signal (FPS - smouthFPS)^2 // Also scale it by a percentage for fine tuning (default is 100%) - float currentVarianceFPS = (currentSmoothFPS - currentFPS); + float currentVarianceFPS = (currentSmoothFPS - currentNowFPS); currentVarianceFPS *= currentVarianceFPS; currentVarianceFPS *= _pidCoefs.w; - auto dt = realTimeDelta; - - auto previous_error = _pidHistory.x; - auto previous_integral = _pidHistory.y; - - auto smoothError = (targetFPS - currentSmoothFPS); - - auto fpsError = smoothError; - - auto errorSquare = smoothError * smoothError; + // evaluate current error between the current smoothFPS and target FPS + // and the sqaure of the error to compare against the Variance + auto currentErrorFPS = (targetFPS - currentSmoothFPS); + auto currentErrorFPSSquare = currentErrorFPS * currentErrorFPS; // Define a noiseCoef that is trying to adjust the error to the FPS target value based on its strength // relative to the current Variance of the FPS signal. @@ -124,41 +109,48 @@ void LODManager::autoAdjustLOD(float realTimeDelta) { // if its within 2x the variance scale the control // and full control if error is bigger than 2x variance auto noiseCoef = 1.0f; - if (errorSquare < currentVarianceFPS) { + if (currentErrorFPSSquare < currentVarianceFPS) { noiseCoef = 0.0f; - } else if (errorSquare < 2.0f * currentVarianceFPS) { - noiseCoef = (errorSquare - currentVarianceFPS) / currentVarianceFPS; + } else if (currentErrorFPSSquare < 2.0f * currentVarianceFPS) { + noiseCoef = (currentErrorFPSSquare - currentVarianceFPS) / currentVarianceFPS; } // The final normalized error is the the error to the FPS target, weighted by the noiseCoef, then normailzed by the target FPS. // it s also clamped in the [-1, 1] range - auto error = noiseCoef * smoothError / targetFPS; + auto error = noiseCoef * currentErrorFPS / targetFPS; error = glm::clamp(error, -1.0f, 1.0f); + // Now we are getting into the P.I.D. controler code + // retreive the history of pid error and integral + auto previous_error = _pidHistory.x; + auto previous_integral = _pidHistory.y; + + // The dt used for temporal values of the controller is the current realTimedelta + // clamped to a reasonable granularity to make sure we are not over reacting + auto dt = std::min(realTimeDelta, LOD_ADJUST_RUNNING_AVG_TIMESCALE); + + // Compute the current integral and clamp to avoid accumulation auto integral = previous_integral + error * dt; glm::clamp(integral, -1.0f, 1.0f); + // Compute derivative auto derivative = (error - previous_error) / dt; + // remember history _pidHistory.x = error; _pidHistory.y = integral; _pidHistory.z = derivative; - auto Kp = _pidCoefs.x; - auto Ki = _pidCoefs.y; - auto Kd = _pidCoefs.z; - - _pidOutputs.x = Kp * error; - _pidOutputs.y = Ki * integral; - _pidOutputs.z = Kd * derivative; + // Compute the output of the PID and record intermediate results for tuning + _pidOutputs.x = _pidCoefs.x * error; // Kp * error + _pidOutputs.y = _pidCoefs.y * integral; // Ki * integral + _pidOutputs.z = _pidCoefs.z * derivative; // Kd * derivative auto output = _pidOutputs.x + _pidOutputs.y + _pidOutputs.z; - _pidOutputs.w = output; - auto newSolidAngle = oldSolidAngle + output; - - setLODAngleDeg(newSolidAngle); + // And now add the output of the controller to the LODAngle where we will guarantee it is in the proper range + setLODAngleDeg(oldLODAngle + output); if (oldOctreeSizeScale != _octreeSizeScale) { auto lodToolsDialog = DependencyManager::get()->getLodToolsDialog(); @@ -168,207 +160,6 @@ void LODManager::autoAdjustLOD(float realTimeDelta) { } } -void LODManager::resetLODAdjust() { - _decreaseFPSExpiry = _increaseFPSExpiry = usecTimestampNow() + LOD_AUTO_ADJUST_PERIOD; -} - -void LODManager::setAutomaticLODAdjust(bool value) { - _automaticLODAdjust = value; - emit autoLODChanged(); -} - -float LODManager::getLODLevel() const { - // simpleLOD is a linearized and normalized number that represents how much LOD is being applied. - // It ranges from: - // 1.0 = normal (max) level of detail - // 0.0 = min level of detail - // In other words: as LOD "drops" the value of simpleLOD will also "drop", and it cannot go lower than 0.0. - const float LOG_MIN_LOD_RATIO = logf(ADJUST_LOD_MIN_SIZE_SCALE / ADJUST_LOD_MAX_SIZE_SCALE); - float power = logf(_octreeSizeScale / ADJUST_LOD_MAX_SIZE_SCALE); - float simpleLOD = (LOG_MIN_LOD_RATIO - power) / LOG_MIN_LOD_RATIO; - return simpleLOD; -} - -void LODManager::setLODLevel(float level) { - float simpleLOD = level; - if (!_automaticLODAdjust) { - const float LOG_MIN_LOD_RATIO = logf(ADJUST_LOD_MIN_SIZE_SCALE / ADJUST_LOD_MAX_SIZE_SCALE); - - float power = LOG_MIN_LOD_RATIO - (simpleLOD * LOG_MIN_LOD_RATIO); - float sizeScale = expf(power) * ADJUST_LOD_MAX_SIZE_SCALE; - setOctreeSizeScale(sizeScale); - } -} - -const float MIN_DECREASE_FPS = 0.5f; - -void LODManager::setDesktopLODDecreaseFPS(float fps) { - if (fps < MIN_DECREASE_FPS) { - // avoid divide by zero - fps = MIN_DECREASE_FPS; - } - _desktopMaxRenderTime = (float)MSECS_PER_SECOND / fps; -} - -float LODManager::getDesktopLODDecreaseFPS() const { - return (float)MSECS_PER_SECOND / _desktopMaxRenderTime; -} - -float LODManager::getDesktopLODIncreaseFPS() const { - return glm::min(((float)MSECS_PER_SECOND / _desktopMaxRenderTime) + INCREASE_LOD_GAP_FPS, MAX_LIKELY_DESKTOP_FPS); -} - -void LODManager::setHMDLODDecreaseFPS(float fps) { - if (fps < MIN_DECREASE_FPS) { - // avoid divide by zero - fps = MIN_DECREASE_FPS; - } - _hmdMaxRenderTime = (float)MSECS_PER_SECOND / fps; -} - -float LODManager::getHMDLODDecreaseFPS() const { - return (float)MSECS_PER_SECOND / _hmdMaxRenderTime; -} - -float LODManager::getHMDLODIncreaseFPS() const { - return glm::min(((float)MSECS_PER_SECOND / _hmdMaxRenderTime) + INCREASE_LOD_GAP_FPS, MAX_LIKELY_HMD_FPS); -} - -QString LODManager::getLODFeedbackText() { - // determine granularity feedback - int boundaryLevelAdjust = getBoundaryLevelAdjust(); - QString granularityFeedback; - switch (boundaryLevelAdjust) { - case 0: { - granularityFeedback = QString("."); - } break; - case 1: { - granularityFeedback = QString(" at half of standard granularity."); - } break; - case 2: { - granularityFeedback = QString(" at a third of standard granularity."); - } break; - default: { - granularityFeedback = QString(" at 1/%1th of standard granularity.").arg(boundaryLevelAdjust + 1); - } break; - } - // distance feedback - float octreeSizeScale = getOctreeSizeScale(); - float relativeToDefault = octreeSizeScale / DEFAULT_OCTREE_SIZE_SCALE; - int relativeToTwentyTwenty = 20 / relativeToDefault; - - QString result; - if (relativeToDefault > 1.01f) { - result = QString("20:%1 or %2 times further than average vision%3").arg(relativeToTwentyTwenty).arg(relativeToDefault,0,'f',2).arg(granularityFeedback); - } else if (relativeToDefault > 0.99f) { - result = QString("20:20 or the default distance for average vision%1").arg(granularityFeedback); - } else if (relativeToDefault > 0.01f) { - result = QString("20:%1 or %2 of default distance for average vision%3").arg(relativeToTwentyTwenty).arg(relativeToDefault,0,'f',3).arg(granularityFeedback); - } else { - result = QString("%2 of default distance for average vision%3").arg(relativeToDefault,0,'f',3).arg(granularityFeedback); - } - return result; -} - -bool LODManager::shouldRender(const RenderArgs* args, const AABox& bounds) { - // FIXME - eventually we want to use the render accuracy as an indicator for the level of detail - // to use in rendering. - // float renderAccuracy = calculateRenderAccuracy(args->getViewFrustum().getPosition(), bounds, args->_sizeScale, args->_boundaryLevelAdjust); - // return (renderAccuracy > 0.0f); - - auto pos = args->getViewFrustum().getPosition() - bounds.calcCenter(); - auto dim = bounds.getDimensions(); - auto halfTanSq = 0.25f * glm::dot(dim, dim) / glm::dot(pos, pos); - return (halfTanSq >= args->_solidAngleHalfTanSq); - -}; - -void LODManager::setOctreeSizeScale(float sizeScale) { - _octreeSizeScale = sizeScale; -} - -void LODManager::setBoundaryLevelAdjust(int boundaryLevelAdjust) { - _boundaryLevelAdjust = boundaryLevelAdjust; -} - -void LODManager::loadSettings() { - setDesktopLODDecreaseFPS(desktopLODDecreaseFPS.get()); - setHMDLODDecreaseFPS(hmdLODDecreaseFPS.get()); -} - -void LODManager::saveSettings() { - desktopLODDecreaseFPS.set(getDesktopLODDecreaseFPS()); - hmdLODDecreaseFPS.set(getHMDLODDecreaseFPS()); -} - - -void LODManager::setSmoothScale(float t) { - _smoothScale = glm::max(1.0f, t); -} - -void LODManager::setWorldDetailQuality(float quality) { - - static const float MAX_DESKTOP_FPS = 60; - static const float MAX_HMD_FPS = 90; - static const float MIN_FPS = 10; - static const float LOW = 0.25f; - static const float MEDIUM = 0.5f; - static const float HIGH = 0.75f; - static const float THRASHING_DIFFERENCE = 10; - - bool isLowestValue = quality == LOW; - bool isHMDMode = qApp->isHMDMode(); - - float maxFPS = isHMDMode ? MAX_HMD_FPS : MAX_DESKTOP_FPS; - float desiredFPS = maxFPS /* - THRASHING_DIFFERENCE*/; - - if (!isLowestValue) { - float calculatedFPS = (maxFPS - (maxFPS * quality))/* - THRASHING_DIFFERENCE*/; - desiredFPS = calculatedFPS < MIN_FPS ? MIN_FPS : calculatedFPS; - } - - if (isHMDMode) { - setHMDLODDecreaseFPS(desiredFPS); - } - else { - setDesktopLODDecreaseFPS(desiredFPS); - } - - emit worldDetailQualityChanged(); -} - -float LODManager::getWorldDetailQuality() const { - - - static const float MAX_DESKTOP_FPS = 60; - static const float MAX_HMD_FPS = 90; - static const float MIN_FPS = 10; - static const float LOW = 0.25f; - static const float MEDIUM = 0.5f; - static const float HIGH = 0.75f; - - bool inHMD = qApp->isHMDMode(); - - float increaseFPS = 0; - if (inHMD) { - increaseFPS = getHMDLODDecreaseFPS(); - } else { - increaseFPS = getDesktopLODDecreaseFPS(); - } - float maxFPS = inHMD ? MAX_HMD_FPS : MAX_DESKTOP_FPS; - float percentage = 1.0 - increaseFPS / maxFPS; - - if (percentage <= LOW) { - return LOW; - } - else if (percentage <= MEDIUM) { - return MEDIUM; - } - - return HIGH; -} - - float LODManager::getLODAngleHalfTan() const { return getPerspectiveAccuracyAngleTan(_octreeSizeScale, _boundaryLevelAdjust); } @@ -386,6 +177,10 @@ void LODManager::setLODAngleDeg(float lodAngle) { setOctreeSizeScale(octreeSizeScale); } +void LODManager::setSmoothScale(float t) { + _smoothScale = glm::max(1.0f, t); +} + float LODManager::getPidKp() const { return _pidCoefs.x; } @@ -422,4 +217,189 @@ float LODManager::getPidOd() const { } float LODManager::getPidO() const { return _pidOutputs.w; -} \ No newline at end of file +} + +void LODManager::resetLODAdjust() { + // _decreaseFPSExpiry = _increaseFPSExpiry = usecTimestampNow() + LOD_AUTO_ADJUST_PERIOD; +} + +void LODManager::setAutomaticLODAdjust(bool value) { + _automaticLODAdjust = value; + emit autoLODChanged(); +} + +bool LODManager::shouldRender(const RenderArgs* args, const AABox& bounds) { + // To decide if the bound should be rendered or not at the specified Args->lodAngle, + // we need to compute the apparent angle of the bound from the frustum origin, + // and compare it against the lodAngle, if it is greater or equal we should render the content of that bound. + // we abstract the bound as a sphere centered on the bound center and of radius half diagonal of the bound. + + // Instead of comparing angles, we are comparing the tangent of the half angle which are more efficient to compute: + // we are comparing the square of the half tangent apparent angle for the bound against the LODAngle Half tangent square + // if smaller, the bound is too small and we should NOT render it, return true otherwise. + + // Tangent Adjacent side is eye to bound center vector length + auto pos = args->getViewFrustum().getPosition() - bounds.calcCenter(); + auto halfTanAdjacentSq = glm::dot(pos, pos); + + // Tangent Opposite side is the half length of the dimensions vector of the bound + auto dim = bounds.getDimensions(); + auto halfTanOppositeSq = 0.25f * glm::dot(dim, dim); + + // The test is: + // isVisible = halfTanSq >= lodHalfTanSq = (halfTanOppositeSq / halfTanAdjacentSq) >= lodHalfTanSq + // which we express as below to avoid division + // (halfTanOppositeSq) >= lodHalfTanSq * halfTanAdjacentSq + return (halfTanOppositeSq >= args->_lodAngleHalfTanSq * halfTanAdjacentSq); +}; + +void LODManager::setOctreeSizeScale(float sizeScale) { + _octreeSizeScale = sizeScale; +} + +void LODManager::setBoundaryLevelAdjust(int boundaryLevelAdjust) { + _boundaryLevelAdjust = boundaryLevelAdjust; +} + +QString LODManager::getLODFeedbackText() { + // determine granularity feedback + int boundaryLevelAdjust = getBoundaryLevelAdjust(); + QString granularityFeedback; + switch (boundaryLevelAdjust) { + case 0: { + granularityFeedback = QString("."); + } break; + case 1: { + granularityFeedback = QString(" at half of standard granularity."); + } break; + case 2: { + granularityFeedback = QString(" at a third of standard granularity."); + } break; + default: { + granularityFeedback = QString(" at 1/%1th of standard granularity.").arg(boundaryLevelAdjust + 1); + } break; + } + // distance feedback + float octreeSizeScale = getOctreeSizeScale(); + float relativeToDefault = octreeSizeScale / DEFAULT_OCTREE_SIZE_SCALE; + int relativeToTwentyTwenty = 20 / relativeToDefault; + + QString result; + if (relativeToDefault > 1.01f) { + result = QString("20:%1 or %2 times further than average vision%3").arg(relativeToTwentyTwenty).arg(relativeToDefault, 0, 'f', 2).arg(granularityFeedback); + } + else if (relativeToDefault > 0.99f) { + result = QString("20:20 or the default distance for average vision%1").arg(granularityFeedback); + } + else if (relativeToDefault > 0.01f) { + result = QString("20:%1 or %2 of default distance for average vision%3").arg(relativeToTwentyTwenty).arg(relativeToDefault, 0, 'f', 3).arg(granularityFeedback); + } + else { + result = QString("%2 of default distance for average vision%3").arg(relativeToDefault, 0, 'f', 3).arg(granularityFeedback); + } + return result; +} + +void LODManager::loadSettings() { + setDesktopLODTargetFPS(desktopLODDecreaseFPS.get()); + setHMDLODTargetFPS(hmdLODDecreaseFPS.get()); +} + +void LODManager::saveSettings() { + desktopLODDecreaseFPS.set(getDesktopLODTargetFPS()); + hmdLODDecreaseFPS.set(getHMDLODTargetFPS()); +} + +const float MIN_DECREASE_FPS = 0.5f; + +void LODManager::setDesktopLODTargetFPS(float fps) { + if (fps < MIN_DECREASE_FPS) { + // avoid divide by zero + fps = MIN_DECREASE_FPS; + } + _desktopTargetFPS = fps; +} + +float LODManager::getDesktopLODTargetFPS() const { + return _desktopTargetFPS; +} + +void LODManager::setHMDLODTargetFPS(float fps) { + if (fps < MIN_DECREASE_FPS) { + // avoid divide by zero + fps = MIN_DECREASE_FPS; + } + _hmdTargetFPS = fps; +} + +float LODManager::getHMDLODTargetFPS() const { + return _hmdTargetFPS; +} + +float LODManager::getLODTargetFPS() const { + if (qApp->isHMDMode()) { + return getHMDLODTargetFPS(); + } + return getDesktopLODTargetFPS(); +} + +void LODManager::setWorldDetailQuality(float quality) { + static const float MIN_FPS = 10; + static const float LOW = 0.25f; + + bool isLowestValue = quality == LOW; + bool isHMDMode = qApp->isHMDMode(); + + float maxFPS = isHMDMode ? LOD_MAX_LIKELY_HMD_FPS : LOD_MAX_LIKELY_DESKTOP_FPS; + float desiredFPS = maxFPS; + + if (!isLowestValue) { + float calculatedFPS = (maxFPS - (maxFPS * quality)); + desiredFPS = calculatedFPS < MIN_FPS ? MIN_FPS : calculatedFPS; + } + + if (isHMDMode) { + setHMDLODTargetFPS(desiredFPS); + } + else { + setDesktopLODTargetFPS(desiredFPS); + } + + emit worldDetailQualityChanged(); +} + +float LODManager::getWorldDetailQuality() const { + + static const float LOW = 0.25f; + static const float MEDIUM = 0.5f; + static const float HIGH = 0.75f; + + bool inHMD = qApp->isHMDMode(); + + float targetFPS = 0; + if (inHMD) { + targetFPS = getHMDLODTargetFPS(); + } else { + targetFPS = getDesktopLODTargetFPS(); + } + float maxFPS = inHMD ? LOD_MAX_LIKELY_HMD_FPS : LOD_MAX_LIKELY_DESKTOP_FPS; + float percentage = 1.0 - targetFPS / maxFPS; + + if (percentage <= LOW) { + return LOW; + } + else if (percentage <= MEDIUM) { + return MEDIUM; + } + + return HIGH; +} + + +void LODManager::setLODQualityLevel(float quality) { + _lodQualityLevel; +} + +float LODManager::getLODQualityLevel() const { + return _lodQualityLevel; +} diff --git a/interface/src/LODManager.h b/interface/src/LODManager.h index 6843744d16..0af745bcf4 100644 --- a/interface/src/LODManager.h +++ b/interface/src/LODManager.h @@ -19,20 +19,11 @@ #include #include -const float DEFAULT_DESKTOP_LOD_DOWN_FPS = 30.0f; -const float DEFAULT_HMD_LOD_DOWN_FPS = 34.0f; -const float DEFAULT_DESKTOP_MAX_RENDER_TIME = (float)MSECS_PER_SECOND / DEFAULT_DESKTOP_LOD_DOWN_FPS; // msec -const float DEFAULT_HMD_MAX_RENDER_TIME = (float)MSECS_PER_SECOND / DEFAULT_HMD_LOD_DOWN_FPS; // msec -const float MAX_LIKELY_DESKTOP_FPS = 61.0f; // this is essentially, V-synch - 1 fps -const float MAX_LIKELY_HMD_FPS = 91.0f; // this is essentially, V-synch - 1 fps -const float INCREASE_LOD_GAP_FPS = 10.0f; // fps -// The default value DEFAULT_OCTREE_SIZE_SCALE means you can be 400 meters away from a 1 meter object in order to see it (which is ~20:20 vision). -const float ADJUST_LOD_MAX_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE; -// This controls how low the auto-adjust LOD will go. We want a minimum vision of ~20:500 or 0.04 of default -// const float ADJUST_LOD_MIN_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE * 0.04f; -// const float ADJUST_LOD_MIN_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE * 0.02f; -const float ADJUST_LOD_MIN_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE * 0.01f; +const float LOD_DEFAULT_QUALITY_LEVEL = 0.5f; // default quality level setting is Mid +const float LOD_MAX_LIKELY_DESKTOP_FPS = 60.0f; // this is essentially, V-synch fps +const float LOD_MAX_LIKELY_HMD_FPS = 90.0f; // this is essentially, V-synch fps +const float LOD_OFFSET_FPS = 5.0f; // offset of FPS to add for computing the target framerate class AABox; @@ -55,41 +46,42 @@ class AABox; class LODManager : public QObject, public Dependency { Q_OBJECT - SINGLETON_DEPENDENCY + SINGLETON_DEPENDENCY - Q_PROPERTY(float presentTime READ getPresentTime) - Q_PROPERTY(float engineRunTime READ getEngineRunTime) - Q_PROPERTY(float batchTime READ getBatchTime) - Q_PROPERTY(float gpuTime READ getGPUTime) + Q_PROPERTY(float worldDetailQuality READ getWorldDetailQuality WRITE setWorldDetailQuality NOTIFY worldDetailQualityChanged) - Q_PROPERTY(float avgRenderTime READ getAverageRenderTime) - Q_PROPERTY(float fps READ getMaxTheoreticalFPS) + Q_PROPERTY(float lodQualityLevel READ getLODQualityLevel WRITE setLODQualityLevel NOTIFY lodQualityLevelChanged) - Q_PROPERTY(float smoothRenderTime READ getSmoothRenderTime) - Q_PROPERTY(float smoothFPS READ getSmoothFPS) - Q_PROPERTY(float smoothScale READ getSmoothScale WRITE setSmoothScale) + Q_PROPERTY(bool automaticLODAdjust READ getAutomaticLODAdjust WRITE setAutomaticLODAdjust NOTIFY autoLODChanged) - Q_PROPERTY(float lodLevel READ getLODLevel WRITE setLODLevel NOTIFY LODChanged) - Q_PROPERTY(float lodDecreaseFPS READ getLODDecreaseFPS) - Q_PROPERTY(float lodIncreaseFPS READ getLODIncreaseFPS) - Q_PROPERTY(bool automaticLODAdjust READ getAutomaticLODAdjust WRITE setAutomaticLODAdjust NOTIFY autoLODChanged) + Q_PROPERTY(float presentTime READ getPresentTime) + Q_PROPERTY(float engineRunTime READ getEngineRunTime) + Q_PROPERTY(float batchTime READ getBatchTime) + Q_PROPERTY(float gpuTime READ getGPUTime) - Q_PROPERTY(float worldDetailQuality READ getWorldDetailQuality WRITE setWorldDetailQuality NOTIFY worldDetailQualityChanged) + Q_PROPERTY(float nowRenderTime READ getNowRenderTime) + Q_PROPERTY(float nowRenderFPS READ getNowRenderFPS) - Q_PROPERTY(float lodAngleDeg READ getLODAngleDeg WRITE setLODAngleDeg) + Q_PROPERTY(float smoothScale READ getSmoothScale WRITE setSmoothScale) + Q_PROPERTY(float smoothRenderTime READ getSmoothRenderTime) + Q_PROPERTY(float smoothRenderFPS READ getSmoothRenderFPS) - Q_PROPERTY(float pidKp READ getPidKp WRITE setPidKp) - Q_PROPERTY(float pidKi READ getPidKi WRITE setPidKi) - Q_PROPERTY(float pidKd READ getPidKd WRITE setPidKd) - Q_PROPERTY(float pidKv READ getPidKv WRITE setPidKv) + Q_PROPERTY(float lodTargetFPS READ getLODTargetFPS) - Q_PROPERTY(float pidOp READ getPidOp) - Q_PROPERTY(float pidOi READ getPidOi) - Q_PROPERTY(float pidOd READ getPidOd) - Q_PROPERTY(float pidO READ getPidO) + Q_PROPERTY(float lodAngleDeg READ getLODAngleDeg WRITE setLODAngleDeg) + + Q_PROPERTY(float pidKp READ getPidKp WRITE setPidKp) + Q_PROPERTY(float pidKi READ getPidKi WRITE setPidKi) + Q_PROPERTY(float pidKd READ getPidKd WRITE setPidKd) + Q_PROPERTY(float pidKv READ getPidKv WRITE setPidKv) + + Q_PROPERTY(float pidOp READ getPidOp) + Q_PROPERTY(float pidOi READ getPidOi) + Q_PROPERTY(float pidOd READ getPidOd) + Q_PROPERTY(float pidO READ getPidO) public: - + /**jsdoc * @function LODManager.setAutomaticLODAdjust * @param {boolean} value @@ -103,42 +95,31 @@ public: Q_INVOKABLE bool getAutomaticLODAdjust() const { return _automaticLODAdjust; } /**jsdoc - * @function LODManager.setDesktopLODDecreaseFPS + * @function LODManager.setDesktopLODTargetFPS * @param {number} value */ - Q_INVOKABLE void setDesktopLODDecreaseFPS(float value); + Q_INVOKABLE void setDesktopLODTargetFPS(float value); /**jsdoc - * @function LODManager.getDesktopLODDecreaseFPS + * @function LODManager.getDesktopLODTargetFPS * @returns {number} */ - Q_INVOKABLE float getDesktopLODDecreaseFPS() const; + Q_INVOKABLE float getDesktopLODTargetFPS() const; /**jsdoc - * @function LODManager.getDesktopLODIncreaseFPS - * @returns {number} - */ - Q_INVOKABLE float getDesktopLODIncreaseFPS() const; - - /**jsdoc - * @function LODManager.setHMDLODDecreaseFPS + * @function LODManager.setHMDLODTargetFPS * @param {number} value */ - - Q_INVOKABLE void setHMDLODDecreaseFPS(float value); + + Q_INVOKABLE void setHMDLODTargetFPS(float value); /**jsdoc - * @function LODManager.getHMDLODDecreaseFPS + * @function LODManager.getHMDLODTargetFPS * @returns {number} */ - Q_INVOKABLE float getHMDLODDecreaseFPS() const; + Q_INVOKABLE float getHMDLODTargetFPS() const; - /**jsdoc - * @function LODManager.getHMDLODIncreaseFPS - * @returns {number} - */ - Q_INVOKABLE float getHMDLODIncreaseFPS() const; // User Tweakable LOD Items /**jsdoc @@ -172,16 +153,11 @@ public: Q_INVOKABLE int getBoundaryLevelAdjust() const { return _boundaryLevelAdjust; } /**jsdoc - * @function LODManager.getLODDecreaseFPS - * @returns {number} - */ - Q_INVOKABLE float getLODDecreaseFPS() const; + * @function LODManager.getLODTargetFPS + * @returns {number} + */ + Q_INVOKABLE float getLODTargetFPS() const; - /**jsdoc - * @function LODManager.getLODIncreaseFPS - * @returns {number} - */ - Q_INVOKABLE float getLODIncreaseFPS() const; float getPresentTime() const { return _presentTime; } float getEngineRunTime() const { return _engineRunTime; } @@ -196,22 +172,21 @@ public: void saveSettings(); void resetLODAdjust(); + float getNowRenderTime() const { return _nowRenderTime; }; + float getNowRenderFPS() const { return (float)MSECS_PER_SECOND / _nowRenderTime; }; + void setSmoothScale(float t); float getSmoothScale() const { return _smoothScale; } - float getAverageRenderTime() const { return _avgRenderTime; }; - float getMaxTheoreticalFPS() const { return (float)MSECS_PER_SECOND / _avgRenderTime; }; - float getSmoothRenderTime() const { return _smoothRenderTime; }; - float getSmoothFPS() const { return (float)MSECS_PER_SECOND / _smoothRenderTime; }; - - - float getLODLevel() const; - void setLODLevel(float level); + float getSmoothRenderFPS() const { return (float)MSECS_PER_SECOND / _smoothRenderTime; }; void setWorldDetailQuality(float quality); float getWorldDetailQuality() const; + void setLODQualityLevel(float quality); + float getLODQualityLevel() const; + float getLODAngleDeg() const; void setLODAngleDeg(float lodAngle); float getLODAngleHalfTan() const; @@ -225,12 +200,15 @@ public: void setPidKi(float k); void setPidKd(float k); void setPidKv(float t); - + float getPidOp() const; float getPidOi() const; float getPidOd() const; float getPidO() const; + static const float DEFAULT_DESKTOP_LOD_DOWN_FPS; + static const float DEFAULT_HMD_LOD_DOWN_FPS; + signals: /**jsdoc @@ -245,24 +223,28 @@ signals: */ void LODDecreased(); - void LODChanged(); void autoLODChanged(); + void lodQualityLevelChanged(); void worldDetailQualityChanged(); private: LODManager(); bool _automaticLODAdjust = true; - float _presentTime { 0.0f }; // msec - float _engineRunTime { 0.0f }; // msec - float _batchTime{ 0.0f }; // msec - float _gpuTime { 0.0f }; // msec - float _smoothScale{ 8.0f }; - float _avgRenderTime { 0.0f }; // msec - float _smoothRenderTime{ 0.0f }; - float _desktopMaxRenderTime { DEFAULT_DESKTOP_MAX_RENDER_TIME }; - float _hmdMaxRenderTime { DEFAULT_HMD_MAX_RENDER_TIME }; + float _presentTime{ 0.0f }; // msec + float _engineRunTime{ 0.0f }; // msec + float _batchTime{ 0.0f }; // msec + float _gpuTime{ 0.0f }; // msec + + float _nowRenderTime{ 0.0f }; // msec + float _smoothScale{ 10.0f }; // smooth is evaluated over 10 times longer than now + float _smoothRenderTime{ 0.0f }; // msec + + float _lodQualityLevel{ LOD_DEFAULT_QUALITY_LEVEL }; + + float _desktopTargetFPS { LOD_OFFSET_FPS + LOD_DEFAULT_QUALITY_LEVEL * LOD_MAX_LIKELY_DESKTOP_FPS }; + float _hmdTargetFPS { LOD_OFFSET_FPS + LOD_DEFAULT_QUALITY_LEVEL * LOD_MAX_LIKELY_HMD_FPS }; float _octreeSizeScale = DEFAULT_OCTREE_SIZE_SCALE; int _boundaryLevelAdjust = 0; @@ -270,9 +252,6 @@ private: glm::vec4 _pidCoefs{ 1.0f, 0.0f, 0.0f, 1.0f }; // Kp, Ki, Kd, Kv glm::vec4 _pidHistory{ 0.0f }; glm::vec4 _pidOutputs{ 0.0f }; - - uint64_t _decreaseFPSExpiry { 0 }; - uint64_t _increaseFPSExpiry { 0 }; }; #endif // hifi_LODManager_h diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index a271e9436c..951925214c 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -55,54 +55,6 @@ void setupPreferences() { // Graphics quality static const QString GRAPHICS_QUALITY { "Graphics Quality" }; { - /* static const float MAX_DESKTOP_FPS = 60; - static const float MAX_HMD_FPS = 90; - static const float MIN_FPS = 10; - static const float LOW = 0.25f; - static const float MEDIUM = 0.5f; - static const float HIGH = 0.75f; - auto getter = []()->float { - auto lodManager = DependencyManager::get(); - bool inHMD = qApp->isHMDMode(); - - float increaseFPS = 0; - if (inHMD) { - increaseFPS = lodManager->getHMDLODDecreaseFPS(); - } else { - increaseFPS = lodManager->getDesktopLODDecreaseFPS(); - } - float maxFPS = inHMD ? MAX_HMD_FPS : MAX_DESKTOP_FPS; - float percentage = increaseFPS / maxFPS; - - if (percentage >= HIGH) { - return LOW; - } else if (percentage >= LOW) { - return MEDIUM; - } - return HIGH; - }; - - auto setter = [](float value) { - static const float THRASHING_DIFFERENCE = 10; - auto lodManager = DependencyManager::get(); - - bool isLowestValue = value == LOW; - bool isHMDMode = qApp->isHMDMode(); - - float maxFPS = isHMDMode ? MAX_HMD_FPS : MAX_DESKTOP_FPS; - float desiredFPS = maxFPS - THRASHING_DIFFERENCE; - - if (!isLowestValue) { - float calculatedFPS = (maxFPS - (maxFPS * value)) - THRASHING_DIFFERENCE; - desiredFPS = calculatedFPS < MIN_FPS ? MIN_FPS : calculatedFPS; - } - - if (isHMDMode) { - lodManager->setHMDLODDecreaseFPS(desiredFPS); - } else { - lodManager->setDesktopLODDecreaseFPS(desiredFPS); - } - };*/ auto getter = []()->float { return DependencyManager::get()->getWorldDetailQuality(); }; diff --git a/libraries/render/src/render/Args.h b/libraries/render/src/render/Args.h index 589945e9c7..dd061c0092 100644 --- a/libraries/render/src/render/Args.h +++ b/libraries/render/src/render/Args.h @@ -73,16 +73,16 @@ namespace render { Args(const gpu::ContextPointer& context, float sizeScale = 1.0f, int boundaryLevelAdjust = 0, - float solidAngleHalfTan = 0.1f, + float lodAngleHalfTan = 0.1f, RenderMode renderMode = DEFAULT_RENDER_MODE, DisplayMode displayMode = MONO, DebugFlags debugFlags = RENDER_DEBUG_NONE, gpu::Batch* batch = nullptr) : _context(context), _sizeScale(sizeScale), - _solidAngleHalfTan(solidAngleHalfTan), - _solidAngleHalfTanSq(solidAngleHalfTan * solidAngleHalfTan), _boundaryLevelAdjust(boundaryLevelAdjust), + _lodAngleHalfTan(lodAngleHalfTan), + _lodAngleHalfTanSq(lodAngleHalfTan * lodAngleHalfTan), _renderMode(renderMode), _displayMode(displayMode), _debugFlags(debugFlags), @@ -111,8 +111,8 @@ namespace render { float _sizeScale { 1.0f }; int _boundaryLevelAdjust { 0 }; - float _solidAngleHalfTan{ 0.1f }; - float _solidAngleHalfTanSq{ _solidAngleHalfTan * _solidAngleHalfTan }; + float _lodAngleHalfTan{ 0.1f }; + float _lodAngleHalfTanSq{ _lodAngleHalfTan * _lodAngleHalfTan }; RenderMode _renderMode { DEFAULT_RENDER_MODE }; DisplayMode _displayMode { MONO }; diff --git a/libraries/render/src/render/CullTask.cpp b/libraries/render/src/render/CullTask.cpp index 7d03f67d3f..b2930032a3 100644 --- a/libraries/render/src/render/CullTask.cpp +++ b/libraries/render/src/render/CullTask.cpp @@ -155,7 +155,7 @@ void FetchSpatialTree::run(const RenderContextPointer& renderContext, const Inpu // Octree selection! float threshold = 0.0f; if (queryFrustum.isPerspective()) { - threshold = getPerspectiveAccuracyAngle(args->_sizeScale, args->_boundaryLevelAdjust); + threshold = args->_lodAngleHalfTan; if (frustumResolution.y > 0) { threshold = glm::max(queryFrustum.getFieldOfView() / frustumResolution.y, threshold); } diff --git a/scripts/developer/utilities/render/lod.qml b/scripts/developer/utilities/render/lod.qml index 28cf744394..889d8db836 100644 --- a/scripts/developer/utilities/render/lod.qml +++ b/scripts/developer/utilities/render/lod.qml @@ -217,24 +217,19 @@ Item { valueUnit: "Hz" plots: [ { - prop: "lodIncreaseFPS", - label: "LOD++", + prop: "lodTargetFPS", + label: "target", color: "#66FF66" }, { - prop: "fps", + prop: "nowRenderFPS", label: "FPS", color: "#FFFF55" }, { - prop: "smoothFPS", + prop: "smoothRenderFPS", label: "Smooth FPS", color: "#9999FF" - }, - { - prop: "lodDecreaseFPS", - label: "LOD--", - color: "#FF6666" } ] } From f1443083341336c9aff7dcb06e45f30f94d84d86 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 31 Aug 2018 16:58:59 +1200 Subject: [PATCH 184/545] Make tablet menu page title navigation go back a level --- .../resources/qml/hifi/tablet/TabletMenu.qml | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/interface/resources/qml/hifi/tablet/TabletMenu.qml b/interface/resources/qml/hifi/tablet/TabletMenu.qml index 57c1163eb8..bfbd2d8813 100644 --- a/interface/resources/qml/hifi/tablet/TabletMenu.qml +++ b/interface/resources/qml/hifi/tablet/TabletMenu.qml @@ -23,6 +23,8 @@ FocusScope { property string subMenu: "" signal sendToScript(var message); + HifiConstants { id: hifi } + Rectangle { id: bgNavBar height: 90 @@ -45,24 +47,22 @@ FocusScope { anchors.topMargin: 0 anchors.top: parent.top - Image { + HiFiGlyphs { id: menuRootIcon - width: 40 - height: 40 - source: "../../../icons/tablet-icons/menu-i.svg" + text: hifi.glyphs.backward + size: 72 anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left - anchors.leftMargin: 15 + width: breadcrumbText.text === "Menu" ? 15 : 50 + visible: breadcrumbText.text !== "Menu" MouseArea { anchors.fill: parent hoverEnabled: true onEntered: iconColorOverlay.color = "#1fc6a6"; onExited: iconColorOverlay.color = "#34a2c7"; - // navigate back to root level menu onClicked: { - buildMenu(); - breadcrumbText.text = "Menu"; + menuPopperUpper.closeLastMenu(); tabletRoot.playButtonClickSound(); } } @@ -103,7 +103,6 @@ FocusScope { menuPopperUpper.closeLastMenu(); } - function setRootMenu(rootMenu, subMenu) { tabletMenu.subMenu = subMenu; tabletMenu.rootMenu = rootMenu; From 0ae18febc762753a0b066315f724c7968b388623 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 30 Aug 2018 22:09:48 -0700 Subject: [PATCH 185/545] Removing cruft and warnings --- interface/src/LODManager.cpp | 7 ------- interface/src/ui/Stats.cpp | 36 +++++++++++++++++++----------------- 2 files changed, 19 insertions(+), 24 deletions(-) diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index 738c3dd9fb..48fd44438f 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -36,12 +36,6 @@ LODManager::LODManager() { // faster than the runningAverage is computed, the error between the value and its runningAverage will be // reduced by 1/e every timescale of real-time that passes. const float LOD_ADJUST_RUNNING_AVG_TIMESCALE = 0.08f; // sec -// -// Assuming the measured value is affected by logic invoked by the runningAverage bumping up against its -// thresholds, we expect the adjustment to introduce a step-function. We want the runningAverage to settle -// to the new value BEFORE we test it aginst its thresholds again. Hence we test on a period that is a few -// multiples of the running average timescale: -const uint64_t LOD_AUTO_ADJUST_PERIOD = 4 * (uint64_t)(LOD_ADJUST_RUNNING_AVG_TIMESCALE * (float)USECS_PER_MSEC); // usec // batchTIme is always contained in presentTime. // We favor using batchTime instead of presentTime as a representative value for rendering duration (on present thread) @@ -220,7 +214,6 @@ float LODManager::getPidO() const { } void LODManager::resetLODAdjust() { - // _decreaseFPSExpiry = _increaseFPSExpiry = usecTimestampNow() + LOD_AUTO_ADJUST_PERIOD; } void LODManager::setAutomaticLODAdjust(bool value) { diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index 3fa712d267..1b26c9b621 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -370,27 +370,29 @@ void Stats::updateStats(bool force) { STAT_UPDATE(engineFrameTime, (float) config->getCPURunTime()); STAT_UPDATE(avatarSimulationTime, (float)avatarManager->getAvatarSimulationTime()); - STAT_UPDATE(gpuBuffers, (int)gpu::Context::getBufferGPUCount()); - STAT_UPDATE(gpuBufferMemory, (int)BYTES_TO_MB(gpu::Context::getBufferGPUMemSize())); - STAT_UPDATE(gpuTextures, (int)gpu::Context::getTextureGPUCount()); + if (_expanded) { + STAT_UPDATE(gpuBuffers, (int)gpu::Context::getBufferGPUCount()); + STAT_UPDATE(gpuBufferMemory, (int)BYTES_TO_MB(gpu::Context::getBufferGPUMemSize())); + STAT_UPDATE(gpuTextures, (int)gpu::Context::getTextureGPUCount()); - STAT_UPDATE(glContextSwapchainMemory, (int)BYTES_TO_MB(gl::Context::getSwapchainMemoryUsage())); + STAT_UPDATE(glContextSwapchainMemory, (int)BYTES_TO_MB(gl::Context::getSwapchainMemoryUsage())); - STAT_UPDATE(qmlTextureMemory, (int)BYTES_TO_MB(OffscreenQmlSurface::getUsedTextureMemory())); - STAT_UPDATE(texturePendingTransfers, (int)BYTES_TO_MB(gpu::Context::getTexturePendingGPUTransferMemSize())); - STAT_UPDATE(gpuTextureMemory, (int)BYTES_TO_MB(gpu::Context::getTextureGPUMemSize())); - STAT_UPDATE(gpuTextureResidentMemory, (int)BYTES_TO_MB(gpu::Context::getTextureResidentGPUMemSize())); - STAT_UPDATE(gpuTextureFramebufferMemory, (int)BYTES_TO_MB(gpu::Context::getTextureFramebufferGPUMemSize())); - STAT_UPDATE(gpuTextureResourceMemory, (int)BYTES_TO_MB(gpu::Context::getTextureResourceGPUMemSize())); - STAT_UPDATE(gpuTextureResourceIdealMemory, (int)BYTES_TO_MB(gpu::Context::getTextureResourceIdealGPUMemSize())); - STAT_UPDATE(gpuTextureResourcePopulatedMemory, (int)BYTES_TO_MB(gpu::Context::getTextureResourcePopulatedGPUMemSize())); - STAT_UPDATE(gpuTextureExternalMemory, (int)BYTES_TO_MB(gpu::Context::getTextureExternalGPUMemSize())); + STAT_UPDATE(qmlTextureMemory, (int)BYTES_TO_MB(OffscreenQmlSurface::getUsedTextureMemory())); + STAT_UPDATE(texturePendingTransfers, (int)BYTES_TO_MB(gpu::Context::getTexturePendingGPUTransferMemSize())); + STAT_UPDATE(gpuTextureMemory, (int)BYTES_TO_MB(gpu::Context::getTextureGPUMemSize())); + STAT_UPDATE(gpuTextureResidentMemory, (int)BYTES_TO_MB(gpu::Context::getTextureResidentGPUMemSize())); + STAT_UPDATE(gpuTextureFramebufferMemory, (int)BYTES_TO_MB(gpu::Context::getTextureFramebufferGPUMemSize())); + STAT_UPDATE(gpuTextureResourceMemory, (int)BYTES_TO_MB(gpu::Context::getTextureResourceGPUMemSize())); + STAT_UPDATE(gpuTextureResourceIdealMemory, (int)BYTES_TO_MB(gpu::Context::getTextureResourceIdealGPUMemSize())); + STAT_UPDATE(gpuTextureResourcePopulatedMemory, (int)BYTES_TO_MB(gpu::Context::getTextureResourcePopulatedGPUMemSize())); + STAT_UPDATE(gpuTextureExternalMemory, (int)BYTES_TO_MB(gpu::Context::getTextureExternalGPUMemSize())); #if !defined(Q_OS_ANDROID) - STAT_UPDATE(gpuTextureMemoryPressureState, getTextureMemoryPressureModeString()); + STAT_UPDATE(gpuTextureMemoryPressureState, getTextureMemoryPressureModeString()); #endif - STAT_UPDATE(gpuFreeMemory, (int)BYTES_TO_MB(gpu::Context::getFreeGPUMemSize())); - STAT_UPDATE(rectifiedTextureCount, (int)RECTIFIED_TEXTURE_COUNT.load()); - STAT_UPDATE(decimatedTextureCount, (int)DECIMATED_TEXTURE_COUNT.load()); + STAT_UPDATE(gpuFreeMemory, (int)BYTES_TO_MB(gpu::Context::getFreeGPUMemSize())); + STAT_UPDATE(rectifiedTextureCount, (int)RECTIFIED_TEXTURE_COUNT.load()); + STAT_UPDATE(decimatedTextureCount, (int)DECIMATED_TEXTURE_COUNT.load()); + } gpu::ContextStats gpuFrameStats; gpuContext->getFrameStats(gpuFrameStats); From 371105d0c44e8fd04a4ae7375bf0f64c0dda3b75 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 30 Aug 2018 22:18:34 -0700 Subject: [PATCH 186/545] Removing cruft and warnings --- interface/src/ui/Stats.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/interface/src/ui/Stats.h b/interface/src/ui/Stats.h index ed88f4fc6b..a0453a09c5 100644 --- a/interface/src/ui/Stats.h +++ b/interface/src/ui/Stats.h @@ -93,7 +93,6 @@ private: \ * @property {number} processing - Read-only. * @property {number} processingPending - Read-only. * @property {number} triangles - Read-only. - * @property {number} quads - Read-only. * @property {number} materialSwitches - Read-only. * @property {number} itemConsidered - Read-only. * @property {number} itemOutOfView - Read-only. @@ -250,7 +249,6 @@ class Stats : public QQuickItem { STATS_PROPERTY(int, processingPending, 0) STATS_PROPERTY(int, triangles, 0) STATS_PROPERTY(int, drawcalls, 0) - // STATS_PROPERTY(int, quads, 0) STATS_PROPERTY(int, materialSwitches, 0) STATS_PROPERTY(int, itemConsidered, 0) STATS_PROPERTY(int, itemOutOfView, 0) @@ -743,13 +741,6 @@ signals: */ void drawcallsChanged(); - /**jsdoc - * Triggered when the value of the quads property changes. - * @function Stats.quadsChanged - * @returns {Signal} - */ - // void quadsChanged(); - /**jsdoc * Triggered when the value of the materialSwitches property changes. * @function Stats.materialSwitchesChanged From 969d16262f046606469e89f0bcf0421c3082e90c Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 30 Aug 2018 22:20:30 -0700 Subject: [PATCH 187/545] Removing cruft and warnings --- scripts/developer/utilities/render/lod.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/scripts/developer/utilities/render/lod.js b/scripts/developer/utilities/render/lod.js index 632f4e50c5..f3e4208034 100644 --- a/scripts/developer/utilities/render/lod.js +++ b/scripts/developer/utilities/render/lod.js @@ -56,7 +56,6 @@ presentationMode: Desktop.PresentationMode.NATIVE, size: {x: 400, y: 600} }); - // window.setPosition(200, 50); window.closed.connect(killWindow); window.fromQml.connect(fromQml); onScreen = true @@ -94,11 +93,7 @@ function onScreenChanged(type, url) { if (onTablet) { - if (url === QMLAPP_URL) { - onAppScreen = true; - } else { - onAppScreen = false; - } + onAppScreen = (url === QMLAPP_URL); button.editProperties({isActive: onAppScreen}); wireEventBridge(onAppScreen); From 764f75c3404472e994dc5c35cba14ef6be8bbe0e Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 30 Aug 2018 22:26:45 -0700 Subject: [PATCH 188/545] including review feedback --- interface/src/LODManager.cpp | 2 +- interface/src/LODManager.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index 48fd44438f..c1ff6cfd6a 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -72,7 +72,7 @@ void LODManager::autoAdjustLOD(float realTimeDelta) { float smoothBlend = (realTimeDelta < LOD_ADJUST_RUNNING_AVG_TIMESCALE * _smoothScale) ? realTimeDelta / (LOD_ADJUST_RUNNING_AVG_TIMESCALE * _smoothScale) : 1.0f; _smoothRenderTime = (1.0f - smoothBlend) * _smoothRenderTime + smoothBlend * maxRenderTime; // msec - if (!_automaticLODAdjust || _nowRenderTime == 0.0f) { + if (!_automaticLODAdjust || _nowRenderTime == 0.0f || _smoothRenderTime == 0.0f) { // early exit return; } diff --git a/interface/src/LODManager.h b/interface/src/LODManager.h index 0af745bcf4..1452c714e9 100644 --- a/interface/src/LODManager.h +++ b/interface/src/LODManager.h @@ -173,13 +173,13 @@ public: void resetLODAdjust(); float getNowRenderTime() const { return _nowRenderTime; }; - float getNowRenderFPS() const { return (float)MSECS_PER_SECOND / _nowRenderTime; }; + float getNowRenderFPS() const { return (_nowRenderTime > 0.0f ? (float)MSECS_PER_SECOND / _nowRenderTime : 0.0f); }; void setSmoothScale(float t); float getSmoothScale() const { return _smoothScale; } float getSmoothRenderTime() const { return _smoothRenderTime; }; - float getSmoothRenderFPS() const { return (float)MSECS_PER_SECOND / _smoothRenderTime; }; + float getSmoothRenderFPS() const { return (_smoothRenderTime > 0.0f ? (float)MSECS_PER_SECOND / _smoothRenderTime : 0.0f); }; void setWorldDetailQuality(float quality); float getWorldDetailQuality() const; From b6d23843dde70d5970c61d025a48a35606491ac9 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Thu, 30 Aug 2018 22:32:02 -0700 Subject: [PATCH 189/545] adding fix to domain redirection URL --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a927853fb0..86a1421127 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1199,7 +1199,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo }); connect(&domainHandler, &DomainHandler::domainConnectionRefused, this, &Application::domainConnectionRefused); - &domainHandler.setErrorDomainURL(QUrl(REDIRECT_HIFI_ADDRESS)); + nodeList->getDomainHandler().setErrorDomainURL(QUrl(REDIRECT_HIFI_ADDRESS)); // We could clear ATP assets only when changing domains, but it's possible that the domain you are connected // to has gone down and switched to a new content set, so when you reconnect the cached ATP assets will no longer be valid. From eb5f6c8eb30e4bd8ea997b81d4480b05181f9610 Mon Sep 17 00:00:00 2001 From: sam gateau Date: Fri, 31 Aug 2018 09:07:34 -0700 Subject: [PATCH 190/545] ardressing coding standard --- interface/src/LODManager.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index c1ff6cfd6a..87771f1c6f 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -280,14 +280,11 @@ QString LODManager::getLODFeedbackText() { QString result; if (relativeToDefault > 1.01f) { result = QString("20:%1 or %2 times further than average vision%3").arg(relativeToTwentyTwenty).arg(relativeToDefault, 0, 'f', 2).arg(granularityFeedback); - } - else if (relativeToDefault > 0.99f) { + } else if (relativeToDefault > 0.99f) { result = QString("20:20 or the default distance for average vision%1").arg(granularityFeedback); - } - else if (relativeToDefault > 0.01f) { + } else if (relativeToDefault > 0.01f) { result = QString("20:%1 or %2 of default distance for average vision%3").arg(relativeToTwentyTwenty).arg(relativeToDefault, 0, 'f', 3).arg(granularityFeedback); - } - else { + } else { result = QString("%2 of default distance for average vision%3").arg(relativeToDefault, 0, 'f', 3).arg(granularityFeedback); } return result; From 262fdb3c28ccc76fc788ef69929f0095b11cd0e1 Mon Sep 17 00:00:00 2001 From: sam gateau Date: Fri, 31 Aug 2018 09:09:22 -0700 Subject: [PATCH 191/545] ardressing coding standard --- interface/src/LODManager.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index 87771f1c6f..8f1289f9f2 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -350,8 +350,7 @@ void LODManager::setWorldDetailQuality(float quality) { if (isHMDMode) { setHMDLODTargetFPS(desiredFPS); - } - else { + } else { setDesktopLODTargetFPS(desiredFPS); } @@ -377,8 +376,7 @@ float LODManager::getWorldDetailQuality() const { if (percentage <= LOW) { return LOW; - } - else if (percentage <= MEDIUM) { + } else if (percentage <= MEDIUM) { return MEDIUM; } From 6bd1ab5ae05a4296b7ea68b35f6d734d3f3a2ede Mon Sep 17 00:00:00 2001 From: sam gateau Date: Fri, 31 Aug 2018 09:18:33 -0700 Subject: [PATCH 192/545] fixing a bad constant --- interface/src/LODManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index 8f1289f9f2..ec50190ddf 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -42,7 +42,7 @@ const float LOD_ADJUST_RUNNING_AVG_TIMESCALE = 0.08f; // sec // if batchTime + cushionTime < presentTime. // since we are shooting for fps around 60, 90Hz, the ideal frames are around 10ms // so we are picking a cushion time of 3ms -const float LOD_BATCH_TO_PRESENT_CUSHION_TIME = 10.0f; // msec +const float LOD_BATCH_TO_PRESENT_CUSHION_TIME = 3.0f; // msec void LODManager::setRenderTimes(float presentTime, float engineRunTime, float batchTime, float gpuTime) { _presentTime = presentTime; From 84ad5c79f9e323760efca6259f5d78fa304abdda Mon Sep 17 00:00:00 2001 From: sam gateau Date: Fri, 31 Aug 2018 11:09:16 -0700 Subject: [PATCH 193/545] fixing a no op --- interface/src/LODManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index ec50190ddf..a64e28bea4 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -385,7 +385,7 @@ float LODManager::getWorldDetailQuality() const { void LODManager::setLODQualityLevel(float quality) { - _lodQualityLevel; + _lodQualityLevel = quality; } float LODManager::getLODQualityLevel() const { From d01b438cb320a7ccc0aa8a0085e86940bb73c09c Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 31 Aug 2018 11:25:17 -0700 Subject: [PATCH 194/545] CR --- interface/src/avatar/AvatarManager.cpp | 6 ++++-- .../graphics/src/graphics/BufferViewHelpers.h | 14 ++++++------- libraries/shared/src/AABox.cpp | 20 +++++++++++++++++++ libraries/shared/src/AABox.h | 9 +++++++++ libraries/shared/src/GLMHelpers.h | 11 +++++++--- tests/shared/src/AACubeTests.cpp | 3 ++- tests/shared/src/GLMHelpersTests.cpp | 2 +- 7 files changed, 50 insertions(+), 15 deletions(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index af9d9ad6b1..bd98549510 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -264,9 +264,11 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { const SortableAvatar& newSortData = *it; const auto newAvatar = std::static_pointer_cast(newSortData.getAvatar()); bool inView = newSortData.getPriority() > OUT_OF_VIEW_THRESHOLD; - if (inView && newAvatar->hasNewJointData()) { - numAVatarsNotUpdated++; + // Once we reach an avatar that's not in view, all avatars after it will also be out of view + if (!inView) { + break; } + numAVatarsNotUpdated += (int)(newAvatar->hasNewJointData()); ++it; } break; diff --git a/libraries/graphics/src/graphics/BufferViewHelpers.h b/libraries/graphics/src/graphics/BufferViewHelpers.h index 7c37c75163..026e7b53a3 100644 --- a/libraries/graphics/src/graphics/BufferViewHelpers.h +++ b/libraries/graphics/src/graphics/BufferViewHelpers.h @@ -56,18 +56,16 @@ namespace buffer_helpers { tangent = glm::clamp(tangent, -1.0f, 1.0f); normal *= 511.0f; tangent *= 511.0f; - normal = fastRoundf(normal); - tangent = fastRoundf(tangent); glm::detail::i10i10i10i2 normalStruct; glm::detail::i10i10i10i2 tangentStruct; - normalStruct.data.x = int(normal.x); - normalStruct.data.y = int(normal.y); - normalStruct.data.z = int(normal.z); + normalStruct.data.x = fastLrintf(normal.x); + normalStruct.data.y = fastLrintf(normal.y); + normalStruct.data.z = fastLrintf(normal.z); normalStruct.data.w = 0; - tangentStruct.data.x = int(tangent.x); - tangentStruct.data.y = int(tangent.y); - tangentStruct.data.z = int(tangent.z); + tangentStruct.data.x = fastLrintf(tangent.x); + tangentStruct.data.y = fastLrintf(tangent.y); + tangentStruct.data.z = fastLrintf(tangent.z); tangentStruct.data.w = 0; packedNormal = normalStruct.pack; packedTangent = tangentStruct.pack; diff --git a/libraries/shared/src/AABox.cpp b/libraries/shared/src/AABox.cpp index e537c3e56a..ff6c2a4e6e 100644 --- a/libraries/shared/src/AABox.cpp +++ b/libraries/shared/src/AABox.cpp @@ -79,6 +79,16 @@ void AABox::setBox(const glm::vec3& corner, const glm::vec3& scale) { glm::vec3 AABox::getFarthestVertex(const glm::vec3& normal) const { glm::vec3 result = _corner; + // This is a branchless version of: + //if (normal.x > 0.0f) { + // result.x += _scale.x; + //} + //if (normal.y > 0.0f) { + // result.y += _scale.y; + //} + //if (normal.z > 0.0f) { + // result.z += _scale.z; + //} float blend = (float)(normal.x > 0.0f); result.x += blend * _scale.x + (1.0f - blend) * 0.0f; blend = (float)(normal.y > 0.0f); @@ -90,6 +100,16 @@ glm::vec3 AABox::getFarthestVertex(const glm::vec3& normal) const { glm::vec3 AABox::getNearestVertex(const glm::vec3& normal) const { glm::vec3 result = _corner; + // This is a branchless version of: + //if (normal.x < 0.0f) { + // result.x += _scale.x; + //} + //if (normal.y < 0.0f) { + // result.y += _scale.y; + //} + //if (normal.z < 0.0f) { + // result.z += _scale.z; + //} float blend = (float)(normal.x < 0.0f); result.x += blend * _scale.x + (1.0f - blend) * 0.0f; blend = (float)(normal.y < 0.0f); diff --git a/libraries/shared/src/AABox.h b/libraries/shared/src/AABox.h index a56615c40e..e0bb1343f8 100644 --- a/libraries/shared/src/AABox.h +++ b/libraries/shared/src/AABox.h @@ -86,6 +86,15 @@ public: AABox clamp(float min, float max) const; inline AABox& operator+=(const glm::vec3& point) { + // Branchless version of: + //if (isInvalid()) { + // _corner = glm::min(_corner, point); + //} else { + // glm::vec3 maximum(_corner + _scale); + // _corner = glm::min(_corner, point); + // maximum = glm::max(maximum, point); + // _scale = maximum - _corner; + //} float blend = (float)isInvalid(); glm::vec3 maximumScale(glm::max(_scale, point - _corner)); _corner = glm::min(_corner, point); diff --git a/libraries/shared/src/GLMHelpers.h b/libraries/shared/src/GLMHelpers.h index 619f8172d5..96219ea48c 100644 --- a/libraries/shared/src/GLMHelpers.h +++ b/libraries/shared/src/GLMHelpers.h @@ -316,11 +316,16 @@ inline void glm_mat4u_mul(const glm::mat4& m1, const glm::mat4& m2, glm::mat4& r #endif } -inline glm::vec3 fastRoundf(const glm::vec3& vec) { +// convert float to int, using round-to-nearest-even (undefined on overflow) +inline int fastLrintf(float x) { #if GLM_ARCH & GLM_ARCH_SSE2_BIT - return glm::vec3(_mm_cvt_ss2si(_mm_set_ss(vec.x)), _mm_cvt_ss2si(_mm_set_ss(vec.y)), _mm_cvt_ss2si(_mm_set_ss(vec.z))); + return _mm_cvt_ss2si(_mm_set_ss(x)); #else - return glm::round(vec); + // return lrintf(x); + static_assert(std::numeric_limits::is_iec559, "Requires IEEE-754 double precision format"); + union { double d; int64_t i; } bits = { (double)x }; + bits.d += (3ULL << 51); + return (int)bits.i; #endif } diff --git a/tests/shared/src/AACubeTests.cpp b/tests/shared/src/AACubeTests.cpp index c3c8e3e6f7..4ed3ee2813 100644 --- a/tests/shared/src/AACubeTests.cpp +++ b/tests/shared/src/AACubeTests.cpp @@ -168,12 +168,13 @@ void AACubeTests::rayVsParabolaPerformance() { glm::vec3 origin(0.0f); glm::vec3 direction = glm::normalize(glm::vec3(1.0f)); + glm::vec3 invDirection = 1.0f / direction; float distance; BoxFace face; glm::vec3 normal; auto start = std::chrono::high_resolution_clock::now(); for (auto& cube : cubes) { - if (cube.findRayIntersection(origin, direction, 1.0f / direction, distance, face, normal)) { + if (cube.findRayIntersection(origin, direction, invDirection, distance, face, normal)) { numRayHits++; } } diff --git a/tests/shared/src/GLMHelpersTests.cpp b/tests/shared/src/GLMHelpersTests.cpp index 669bbb8e43..71877e89f6 100644 --- a/tests/shared/src/GLMHelpersTests.cpp +++ b/tests/shared/src/GLMHelpersTests.cpp @@ -234,7 +234,7 @@ void GLMHelpersTests::roundPerf() { auto glmTime = std::chrono::high_resolution_clock::now() - start; start = std::chrono::high_resolution_clock::now(); for (auto& vec : vecs2) { - vec = fastRoundf(vec); + vec = glm::vec3(fastLrintf(vec.x), fastLrintf(vec.y), fastLrintf(vec.z)); } auto manualTime = std::chrono::high_resolution_clock::now() - start; From ec18806546f56a6d35ba4cfc21b3808a3997b3f3 Mon Sep 17 00:00:00 2001 From: sam gateau Date: Fri, 31 Aug 2018 12:15:28 -0700 Subject: [PATCH 195/545] INtegrating in the algorithm, not in the public values the overshoot for the target FPS to make it simpler to understand --- interface/src/LODManager.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index a64e28bea4..1947374b1f 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -19,8 +19,8 @@ #include "ui/DialogsManager.h" #include "InterfaceLogging.h" -const float LODManager::DEFAULT_DESKTOP_LOD_DOWN_FPS = LOD_OFFSET_FPS + LOD_DEFAULT_QUALITY_LEVEL * LOD_MAX_LIKELY_DESKTOP_FPS; -const float LODManager::DEFAULT_HMD_LOD_DOWN_FPS = LOD_OFFSET_FPS + LOD_DEFAULT_QUALITY_LEVEL * LOD_MAX_LIKELY_HMD_FPS; +const float LODManager::DEFAULT_DESKTOP_LOD_DOWN_FPS = LOD_DEFAULT_QUALITY_LEVEL * LOD_MAX_LIKELY_DESKTOP_FPS; +const float LODManager::DEFAULT_HMD_LOD_DOWN_FPS = LOD_DEFAULT_QUALITY_LEVEL * LOD_MAX_LIKELY_HMD_FPS; Setting::Handle desktopLODDecreaseFPS("desktopLODDecreaseFPS", LODManager::DEFAULT_DESKTOP_LOD_DOWN_FPS); Setting::Handle hmdLODDecreaseFPS("hmdLODDecreaseFPS", LODManager::DEFAULT_HMD_LOD_DOWN_FPS); @@ -81,8 +81,10 @@ void LODManager::autoAdjustLOD(float realTimeDelta) { float oldOctreeSizeScale = getOctreeSizeScale(); float oldLODAngle = getLODAngleDeg(); - // Target fps and current fps based on latest measurments - float targetFPS = getLODTargetFPS(); + // Target fps is slightly overshooted by 5hz + float targetFPS = getLODTargetFPS() + LOD_OFFSET_FPS; + + // Current fps based on latest measurments float currentNowFPS = (float)MSECS_PER_SECOND / _nowRenderTime; float currentSmoothFPS = (float)MSECS_PER_SECOND / _smoothRenderTime; From 727bd6b05af29d3edd9b3d23a34428418e553712 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 31 Aug 2018 13:31:26 -0700 Subject: [PATCH 196/545] don't bid for simulation ownership of locked things --- libraries/physics/src/EntityMotionState.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 925cfee740..2c130274bc 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -778,8 +778,10 @@ void EntityMotionState::computeCollisionGroupAndMask(int32_t& group, int32_t& ma bool EntityMotionState::shouldSendBid() const { // NOTE: this method is only ever called when the entity's simulation is NOT locally owned - return _body->isActive() && (_region == workload::Region::R1) && - glm::max(glm::max(VOLUNTEER_SIMULATION_PRIORITY, _bumpedPriority), _entity->getScriptSimulationPriority()) >= _entity->getSimulationPriority(); + return _body->isActive() + && (_region == workload::Region::R1) + && glm::max(glm::max(VOLUNTEER_SIMULATION_PRIORITY, _bumpedPriority), _entity->getScriptSimulationPriority()) >= _entity->getSimulationPriority() + && !_entity->getLocked(); } uint8_t EntityMotionState::computeFinalBidPriority() const { From 028092f80398a1127da3bf019e59675b5192566c Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 31 Aug 2018 13:33:45 -0700 Subject: [PATCH 197/545] fix blendshapes one last time --- libraries/render-utils/src/CauterizedModel.cpp | 4 ++-- libraries/render-utils/src/CauterizedModel.h | 2 +- libraries/render-utils/src/Model.cpp | 6 +++--- libraries/render-utils/src/Model.h | 2 +- libraries/render-utils/src/SoftAttachmentModel.cpp | 4 ++-- libraries/render-utils/src/SoftAttachmentModel.h | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/libraries/render-utils/src/CauterizedModel.cpp b/libraries/render-utils/src/CauterizedModel.cpp index 259036f500..2754697db7 100644 --- a/libraries/render-utils/src/CauterizedModel.cpp +++ b/libraries/render-utils/src/CauterizedModel.cpp @@ -102,7 +102,7 @@ void CauterizedModel::createRenderItemSet() { } } -void CauterizedModel::updateClusterMatrices() { +void CauterizedModel::updateClusterMatrices(bool triggerBlendshapes) { PerformanceTimer perfTimer("CauterizedModel::updateClusterMatrices"); if (!_needsUpdateClusterMatrices || !isLoaded()) { @@ -175,7 +175,7 @@ void CauterizedModel::updateClusterMatrices() { // post the blender if we're not currently waiting for one to finish auto modelBlender = DependencyManager::get(); - if (modelBlender->shouldComputeBlendshapes() && geometry.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) { + if (triggerBlendshapes && modelBlender->shouldComputeBlendshapes() && geometry.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) { _blendedBlendshapeCoefficients = _blendshapeCoefficients; modelBlender->noteRequiresBlend(getThisPointer()); } diff --git a/libraries/render-utils/src/CauterizedModel.h b/libraries/render-utils/src/CauterizedModel.h index 36a96fb006..12cf921e5b 100644 --- a/libraries/render-utils/src/CauterizedModel.h +++ b/libraries/render-utils/src/CauterizedModel.h @@ -33,7 +33,7 @@ public: void createRenderItemSet() override; - virtual void updateClusterMatrices() override; + virtual void updateClusterMatrices(bool triggerBlendshapes = true) override; void updateRenderItems() override; const Model::MeshState& getCauterizeMeshState(int index) const; diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 4158b14223..8287b9cca6 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -976,7 +976,7 @@ bool Model::addToScene(const render::ScenePointer& scene, render::Transaction& transaction, render::Item::Status::Getters& statusGetters) { if (!_addedToScene && isLoaded()) { - updateClusterMatrices(); + updateClusterMatrices(false); if (_modelMeshRenderItems.empty()) { createRenderItemSet(); } @@ -1486,7 +1486,7 @@ void Model::computeMeshPartLocalBounds() { } // virtual -void Model::updateClusterMatrices() { +void Model::updateClusterMatrices(bool triggerBlendshapes) { DETAILED_PERFORMANCE_TIMER("Model::updateClusterMatrices"); if (!_needsUpdateClusterMatrices || !isLoaded()) { @@ -1515,7 +1515,7 @@ void Model::updateClusterMatrices() { // post the blender if we're not currently waiting for one to finish auto modelBlender = DependencyManager::get(); - if (modelBlender->shouldComputeBlendshapes() && geometry.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) { + if (triggerBlendshapes && modelBlender->shouldComputeBlendshapes() && geometry.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) { _blendedBlendshapeCoefficients = _blendshapeCoefficients; modelBlender->noteRequiresBlend(getThisPointer()); } diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 4642515294..5ab50da162 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -159,7 +159,7 @@ public: bool getSnapModelToRegistrationPoint() { return _snapModelToRegistrationPoint; } virtual void simulate(float deltaTime, bool fullUpdate = true); - virtual void updateClusterMatrices(); + virtual void updateClusterMatrices(bool triggerBlendshapes = true); /// Returns a reference to the shared geometry. const Geometry::Pointer& getGeometry() const { return _renderGeometry; } diff --git a/libraries/render-utils/src/SoftAttachmentModel.cpp b/libraries/render-utils/src/SoftAttachmentModel.cpp index f9b90f38ba..93ce8f595a 100644 --- a/libraries/render-utils/src/SoftAttachmentModel.cpp +++ b/libraries/render-utils/src/SoftAttachmentModel.cpp @@ -31,7 +31,7 @@ int SoftAttachmentModel::getJointIndexOverride(int i) const { // virtual // use the _rigOverride matrices instead of the Model::_rig -void SoftAttachmentModel::updateClusterMatrices() { +void SoftAttachmentModel::updateClusterMatrices(bool triggerBlendshapes) { if (!_needsUpdateClusterMatrices) { return; } @@ -78,7 +78,7 @@ void SoftAttachmentModel::updateClusterMatrices() { // post the blender if we're not currently waiting for one to finish auto modelBlender = DependencyManager::get(); - if (modelBlender->shouldComputeBlendshapes() && geometry.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) { + if (triggerBlendshapes && modelBlender->shouldComputeBlendshapes() && geometry.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) { _blendedBlendshapeCoefficients = _blendshapeCoefficients; modelBlender->noteRequiresBlend(getThisPointer()); } diff --git a/libraries/render-utils/src/SoftAttachmentModel.h b/libraries/render-utils/src/SoftAttachmentModel.h index 4335c1634e..03038c35f3 100644 --- a/libraries/render-utils/src/SoftAttachmentModel.h +++ b/libraries/render-utils/src/SoftAttachmentModel.h @@ -27,7 +27,7 @@ public: ~SoftAttachmentModel(); void updateRig(float deltaTime, glm::mat4 parentTransform) override; - void updateClusterMatrices() override; + void updateClusterMatrices(bool triggerBlendshapes = true) override; protected: int getJointIndexOverride(int i) const; From 5067047e52b169a42ffb373fb764561ffa012052 Mon Sep 17 00:00:00 2001 From: sam gateau Date: Fri, 31 Aug 2018 14:24:52 -0700 Subject: [PATCH 198/545] warnings on ubuntu --- interface/src/LODManager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index 1947374b1f..2b5ca9ae8c 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -160,7 +160,7 @@ float LODManager::getLODAngleHalfTan() const { return getPerspectiveAccuracyAngleTan(_octreeSizeScale, _boundaryLevelAdjust); } float LODManager::getLODAngle() const { - return 2.0f * atan(getLODAngleHalfTan()); + return 2.0f * atanf(getLODAngleHalfTan()); } float LODManager::getLODAngleDeg() const { return glm::degrees(getLODAngle()); @@ -367,14 +367,14 @@ float LODManager::getWorldDetailQuality() const { bool inHMD = qApp->isHMDMode(); - float targetFPS = 0; + float targetFPS = 0.0f; if (inHMD) { targetFPS = getHMDLODTargetFPS(); } else { targetFPS = getDesktopLODTargetFPS(); } float maxFPS = inHMD ? LOD_MAX_LIKELY_HMD_FPS : LOD_MAX_LIKELY_DESKTOP_FPS; - float percentage = 1.0 - targetFPS / maxFPS; + float percentage = 1.0f - targetFPS / maxFPS; if (percentage <= LOW) { return LOW; From e1d51a6c425de1f91818bd98901665fcc64aeb8e Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Fri, 31 Aug 2018 15:06:33 -0700 Subject: [PATCH 199/545] Avatar serializing: use memcpy where possible, take copy of joint data to avoid holding lock, etc --- libraries/avatars/src/AvatarData.cpp | 145 ++++++++++----------------- 1 file changed, 51 insertions(+), 94 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 262bf2a567..ca891eb246 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -363,13 +363,13 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent memcpy(destinationBuffer, &packetStateFlags, sizeof(packetStateFlags)); destinationBuffer += sizeof(packetStateFlags); +#define AVATAR_MEMCPY(src) \ + memcpy(destinationBuffer, &(src), sizeof(src)); \ + destinationBuffer += sizeof(src); + if (hasAvatarGlobalPosition) { auto startSection = destinationBuffer; - auto data = reinterpret_cast(destinationBuffer); - data->globalPosition[0] = _globalPosition.x; - data->globalPosition[1] = _globalPosition.y; - data->globalPosition[2] = _globalPosition.z; - destinationBuffer += sizeof(AvatarDataPacket::AvatarGlobalPosition); + AVATAR_MEMCPY(_globalPosition); int numBytes = destinationBuffer - startSection; @@ -380,17 +380,8 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent if (hasAvatarBoundingBox) { auto startSection = destinationBuffer; - auto data = reinterpret_cast(destinationBuffer); - - data->avatarDimensions[0] = _globalBoundingBoxDimensions.x; - data->avatarDimensions[1] = _globalBoundingBoxDimensions.y; - data->avatarDimensions[2] = _globalBoundingBoxDimensions.z; - - data->boundOriginOffset[0] = _globalBoundingBoxOffset.x; - data->boundOriginOffset[1] = _globalBoundingBoxOffset.y; - data->boundOriginOffset[2] = _globalBoundingBoxOffset.z; - - destinationBuffer += sizeof(AvatarDataPacket::AvatarBoundingBox); + AVATAR_MEMCPY(_globalBoundingBoxDimensions); + AVATAR_MEMCPY(_globalBoundingBoxOffset); int numBytes = destinationBuffer - startSection; if (outboundDataRateOut) { @@ -424,13 +415,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent if (hasLookAtPosition) { auto startSection = destinationBuffer; - auto data = reinterpret_cast(destinationBuffer); - auto lookAt = _headData->getLookAtPosition(); - data->lookAtPosition[0] = lookAt.x; - data->lookAtPosition[1] = lookAt.y; - data->lookAtPosition[2] = lookAt.z; - destinationBuffer += sizeof(AvatarDataPacket::LookAtPosition); - + AVATAR_MEMCPY(_headData->getLookAtPosition()); int numBytes = destinationBuffer - startSection; if (outboundDataRateOut) { outboundDataRateOut->lookAtPositionRate.increment(numBytes); @@ -531,12 +516,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent if (hasAvatarLocalPosition) { auto startSection = destinationBuffer; - auto data = reinterpret_cast(destinationBuffer); - auto localPosition = getLocalPosition(); - data->localPosition[0] = localPosition.x; - data->localPosition[1] = localPosition.y; - data->localPosition[2] = localPosition.z; - destinationBuffer += sizeof(AvatarDataPacket::AvatarLocalPosition); + AVATAR_MEMCPY(getLocalPosition()); int numBytes = destinationBuffer - startSection; if (outboundDataRateOut) { @@ -572,14 +552,17 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent auto startSection = destinationBuffer; QReadLocker readLock(&_jointDataLock); + const QVector jointData(_jointData); + readLock.unlock(); // Unlock quickly. + // joint rotation data - int numJoints = _jointData.size(); + int numJoints = jointData.size(); *destinationBuffer++ = (uint8_t)numJoints; unsigned char* validityPosition = destinationBuffer; unsigned char validity = 0; int validityBit = 0; - int numValidityBytes = (int)std::ceil(numJoints / (float)BITS_IN_BYTE); + int numValidityBytes = (numJoints + BITS_IN_BYTE - 1) / BITS_IN_BYTE; #ifdef WANT_DEBUG int rotationSentCount = 0; @@ -595,24 +578,19 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent localSentJointDataOut.resize(numJoints); // Make sure the destination is resized before using it } - float minRotationDOT = !distanceAdjust ? AVATAR_MIN_ROTATION_DOT : getDistanceBasedMinRotationDOT(viewerPosition); + float minRotationDOT = (distanceAdjust && cullSmallChanges) ? getDistanceBasedMinRotationDOT(viewerPosition) : AVATAR_MIN_ROTATION_DOT; - for (int i = 0; i < _jointData.size(); i++) { - const JointData& data = _jointData[i]; + for (int i = 0; i < jointData.size(); i++) { + const JointData& data = jointData[i]; const JointData& last = lastSentJointData[i]; if (!data.rotationIsDefaultPose) { bool mustSend = sendAll || last.rotationIsDefaultPose; if (mustSend || last.rotation != data.rotation) { - bool largeEnoughRotation = true; - if (cullSmallChanges) { - // The dot product for smaller rotations is a smaller number. - // So if the dot() is less than the value, then the rotation is a larger angle of rotation - largeEnoughRotation = fabsf(glm::dot(last.rotation, data.rotation)) < minRotationDOT; - } - - if (mustSend || !cullSmallChanges || largeEnoughRotation) { + // The dot product for larger rotations is a lower number. + // So if the dot() is less than the value, then the rotation is a larger angle of rotation + if (!cullSmallChanges || fabsf(glm::dot(last.rotation, data.rotation)) < minRotationDOT) { validity |= (1 << validityBit); #ifdef WANT_DEBUG rotationSentCount++; @@ -647,17 +625,17 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent destinationBuffer += numValidityBytes; // Move pointer past the validity bytes - float minTranslation = !distanceAdjust ? AVATAR_MIN_TRANSLATION : getDistanceBasedMinTranslationDistance(viewerPosition); + float minTranslation = (distanceAdjust && cullSmallChanges) ? getDistanceBasedMinTranslationDistance(viewerPosition) : AVATAR_MIN_ROTATION_DOT; float maxTranslationDimension = 0.0; - for (int i = 0; i < _jointData.size(); i++) { - const JointData& data = _jointData[i]; + for (int i = 0; i < jointData.size(); i++) { + const JointData& data = jointData[i]; const JointData& last = lastSentJointData[i]; if (!data.translationIsDefaultPose) { bool mustSend = sendAll || last.translationIsDefaultPose; if (mustSend || last.translation != data.translation) { - if (mustSend || !cullSmallChanges || glm::distance(data.translation, lastSentJointData[i].translation) > minTranslation) { + if (!cullSmallChanges || glm::distance(data.translation, lastSentJointData[i].translation) > minTranslation) { validity |= (1 << validityBit); #ifdef WANT_DEBUG translationSentCount++; @@ -707,34 +685,12 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent glm::vec3 mouseFarGrabPosition = extractTranslation(mouseFarGrabMatrix); glm::quat mouseFarGrabRotation = extractRotation(mouseFarGrabMatrix); - data->leftFarGrabPosition[0] = leftFarGrabPosition.x; - data->leftFarGrabPosition[1] = leftFarGrabPosition.y; - data->leftFarGrabPosition[2] = leftFarGrabPosition.z; - - data->leftFarGrabRotation[0] = leftFarGrabRotation.w; - data->leftFarGrabRotation[1] = leftFarGrabRotation.x; - data->leftFarGrabRotation[2] = leftFarGrabRotation.y; - data->leftFarGrabRotation[3] = leftFarGrabRotation.z; - - data->rightFarGrabPosition[0] = rightFarGrabPosition.x; - data->rightFarGrabPosition[1] = rightFarGrabPosition.y; - data->rightFarGrabPosition[2] = rightFarGrabPosition.z; - - data->rightFarGrabRotation[0] = rightFarGrabRotation.w; - data->rightFarGrabRotation[1] = rightFarGrabRotation.x; - data->rightFarGrabRotation[2] = rightFarGrabRotation.y; - data->rightFarGrabRotation[3] = rightFarGrabRotation.z; - - data->mouseFarGrabPosition[0] = mouseFarGrabPosition.x; - data->mouseFarGrabPosition[1] = mouseFarGrabPosition.y; - data->mouseFarGrabPosition[2] = mouseFarGrabPosition.z; - - data->mouseFarGrabRotation[0] = mouseFarGrabRotation.w; - data->mouseFarGrabRotation[1] = mouseFarGrabRotation.x; - data->mouseFarGrabRotation[2] = mouseFarGrabRotation.y; - data->mouseFarGrabRotation[3] = mouseFarGrabRotation.z; - - destinationBuffer += sizeof(AvatarDataPacket::FarGrabJoints); + AVATAR_MEMCPY(leftFarGrabPosition); + AVATAR_MEMCPY(leftFarGrabRotation); + AVATAR_MEMCPY(rightFarGrabPosition); + AVATAR_MEMCPY(rightFarGrabRotation); + AVATAR_MEMCPY(mouseFarGrabPosition); + AVATAR_MEMCPY(mouseFarGrabRotation); int numBytes = destinationBuffer - startSection; @@ -764,8 +720,8 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent if (sentJointDataOut) { // Mark default poses in lastSentJointData, so when they become non-default we send them. - for (int i = 0; i < _jointData.size(); i++) { - const JointData& data = _jointData[i]; + for (int i = 0; i < jointData.size(); i++) { + const JointData& data = jointData[i]; JointData& local = localSentJointDataOut[i]; if (data.rotationIsDefaultPose) { local.rotationIsDefaultPose = true; @@ -778,30 +734,31 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent // Push new sent joint data to sentJointDataOut sentJointDataOut->swap(localSentJointDataOut); } - } - if (hasJointDefaultPoseFlags) { - auto startSection = destinationBuffer; - QReadLocker readLock(&_jointDataLock); + // Always true, currently: + if (hasJointDefaultPoseFlags) { + auto startSection = destinationBuffer; - // write numJoints - int numJoints = _jointData.size(); - *destinationBuffer++ = (uint8_t)numJoints; + // write numJoints + int numJoints = jointData.size(); + *destinationBuffer++ = (uint8_t)numJoints; - // write rotationIsDefaultPose bits - destinationBuffer += writeBitVector(destinationBuffer, numJoints, [&](int i) { - return _jointData[i].rotationIsDefaultPose; - }); + // write rotationIsDefaultPose bits + destinationBuffer += writeBitVector(destinationBuffer, numJoints, [&](int i) { + return jointData[i].rotationIsDefaultPose; + }); - // write translationIsDefaultPose bits - destinationBuffer += writeBitVector(destinationBuffer, numJoints, [&](int i) { - return _jointData[i].translationIsDefaultPose; - }); + // write translationIsDefaultPose bits + destinationBuffer += writeBitVector(destinationBuffer, numJoints, [&](int i) { + return jointData[i].translationIsDefaultPose; + }); - if (outboundDataRateOut) { - size_t numBytes = destinationBuffer - startSection; - outboundDataRateOut->jointDefaultPoseFlagsRate.increment(numBytes); + if (outboundDataRateOut) { + size_t numBytes = destinationBuffer - startSection; + outboundDataRateOut->jointDefaultPoseFlagsRate.increment(numBytes); + } } + } int avatarDataSize = destinationBuffer - startPosition; From 2da533857475223df5f2e2c4159a01588ba8c406 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Fri, 31 Aug 2018 15:24:51 -0700 Subject: [PATCH 200/545] Fix couple of gcc issues --- libraries/avatars/src/AvatarData.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index ca891eb246..4363607e71 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -516,7 +516,8 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent if (hasAvatarLocalPosition) { auto startSection = destinationBuffer; - AVATAR_MEMCPY(getLocalPosition()); + const auto localPosition = getLocalPosition(); + AVATAR_MEMCPY(localPosition); int numBytes = destinationBuffer - startSection; if (outboundDataRateOut) { @@ -677,7 +678,6 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent if (hasGrabJoints) { // the far-grab joints may range further than 3 meters, so we can't use packFloatVec3ToSignedTwoByteFixed etc auto startSection = destinationBuffer; - auto data = reinterpret_cast(destinationBuffer); glm::vec3 leftFarGrabPosition = extractTranslation(leftFarGrabMatrix); glm::quat leftFarGrabRotation = extractRotation(leftFarGrabMatrix); glm::vec3 rightFarGrabPosition = extractTranslation(rightFarGrabMatrix); From 5a0de0f103cda82906cd1d47aa38b190b9d3c470 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Fri, 31 Aug 2018 16:45:39 -0700 Subject: [PATCH 201/545] Small fixes for joint logic --- libraries/avatars/src/AvatarData.cpp | 50 +++++++++++++--------------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 4363607e71..c7a506a782 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -586,22 +586,19 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent const JointData& last = lastSentJointData[i]; if (!data.rotationIsDefaultPose) { - bool mustSend = sendAll || last.rotationIsDefaultPose; - if (mustSend || last.rotation != data.rotation) { - - // The dot product for larger rotations is a lower number. - // So if the dot() is less than the value, then the rotation is a larger angle of rotation - if (!cullSmallChanges || fabsf(glm::dot(last.rotation, data.rotation)) < minRotationDOT) { - validity |= (1 << validityBit); + // The dot product for larger rotations is a lower number. + // So if the dot() is less than the value, then the rotation is a larger angle of rotation + if (sendAll || last.rotationIsDefaultPose || (!cullSmallChanges && last.rotation != data.rotation) + || (cullSmallChanges && glm::dot(last.rotation, data.rotation) < minRotationDOT) ) { + validity |= (1 << validityBit); #ifdef WANT_DEBUG - rotationSentCount++; + rotationSentCount++; #endif - destinationBuffer += packOrientationQuatToSixBytes(destinationBuffer, data.rotation); + destinationBuffer += packOrientationQuatToSixBytes(destinationBuffer, data.rotation); - if (sentJointDataOut) { - localSentJointDataOut[i].rotation = data.rotation; - localSentJointDataOut[i].rotationIsDefaultPose = false; - } + if (sentJointDataOut) { + localSentJointDataOut[i].rotation = data.rotation; + localSentJointDataOut[i].rotationIsDefaultPose = false; } } } @@ -634,24 +631,23 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent const JointData& last = lastSentJointData[i]; if (!data.translationIsDefaultPose) { - bool mustSend = sendAll || last.translationIsDefaultPose; - if (mustSend || last.translation != data.translation) { - if (!cullSmallChanges || glm::distance(data.translation, lastSentJointData[i].translation) > minTranslation) { - validity |= (1 << validityBit); + if (sendAll || last.translationIsDefaultPose || (!cullSmallChanges && last.translation != data.translation) + || (cullSmallChanges && glm::distance(data.translation, lastSentJointData[i].translation) > minTranslation)) { + + validity |= (1 << validityBit); #ifdef WANT_DEBUG - translationSentCount++; + translationSentCount++; #endif - maxTranslationDimension = glm::max(fabsf(data.translation.x), maxTranslationDimension); - maxTranslationDimension = glm::max(fabsf(data.translation.y), maxTranslationDimension); - maxTranslationDimension = glm::max(fabsf(data.translation.z), maxTranslationDimension); + maxTranslationDimension = glm::max(fabsf(data.translation.x), maxTranslationDimension); + maxTranslationDimension = glm::max(fabsf(data.translation.y), maxTranslationDimension); + maxTranslationDimension = glm::max(fabsf(data.translation.z), maxTranslationDimension); - destinationBuffer += - packFloatVec3ToSignedTwoByteFixed(destinationBuffer, data.translation, TRANSLATION_COMPRESSION_RADIX); + destinationBuffer += + packFloatVec3ToSignedTwoByteFixed(destinationBuffer, data.translation, TRANSLATION_COMPRESSION_RADIX); - if (sentJointDataOut) { - localSentJointDataOut[i].translation = data.translation; - localSentJointDataOut[i].translationIsDefaultPose = false; - } + if (sentJointDataOut) { + localSentJointDataOut[i].translation = data.translation; + localSentJointDataOut[i].translationIsDefaultPose = false; } } } From 48680329ec4b29076179eeb04c882408d575d53f Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 29 Aug 2018 21:26:19 -0700 Subject: [PATCH 202/545] mark trait instances needing to be sent on mixer reconnect --- libraries/avatars/src/AvatarData.cpp | 12 +++++++++++- libraries/avatars/src/AvatarData.h | 2 ++ libraries/avatars/src/ClientTraitsHandler.cpp | 6 ++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index b86398501e..ea6dbd7074 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -1895,6 +1895,16 @@ qint64 AvatarData::packTraitInstance(AvatarTraits::TraitType traitType, AvatarTr return bytesWritten; } +void AvatarData::prepareResetTraitInstances() { + if (_clientTraitsHandler) { + _avatarEntitiesLock.withReadLock([this]{ + foreach (auto entityID, _avatarEntityData.keys()) { + _clientTraitsHandler->markInstancedTraitUpdated(AvatarTraits::AvatarEntity, entityID); + } + }); + } +} + void AvatarData::processTrait(AvatarTraits::TraitType traitType, QByteArray traitBinaryData) { if (traitType == AvatarTraits::SkeletonModelURL) { // get the URL from the binary data @@ -2792,7 +2802,7 @@ void AvatarData::setAvatarEntityData(const AvatarEntityMap& avatarEntityData) { if (_clientTraitsHandler) { // if we have a client traits handler, flag any updated or created entities // so that we send changes for them next frame - foreach (auto entityID, _avatarEntityData) { + foreach (auto entityID, _avatarEntityData.keys()) { _clientTraitsHandler->markInstancedTraitUpdated(AvatarTraits::AvatarEntity, entityID); } } diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 0474d07acd..db2b82b0b7 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -964,6 +964,8 @@ public: qint64 packTraitInstance(AvatarTraits::TraitType traitType, AvatarTraits::TraitInstanceID instanceID, ExtendedIODevice& destination, AvatarTraits::TraitVersion traitVersion = AvatarTraits::NULL_TRAIT_VERSION); + void prepareResetTraitInstances(); + void processTrait(AvatarTraits::TraitType traitType, QByteArray traitBinaryData); void processTraitInstance(AvatarTraits::TraitType traitType, AvatarTraits::TraitInstanceID instanceID, QByteArray traitBinaryData); diff --git a/libraries/avatars/src/ClientTraitsHandler.cpp b/libraries/avatars/src/ClientTraitsHandler.cpp index c4073cb86a..a06b53da7c 100644 --- a/libraries/avatars/src/ClientTraitsHandler.cpp +++ b/libraries/avatars/src/ClientTraitsHandler.cpp @@ -37,6 +37,12 @@ void ClientTraitsHandler::resetForNewMixer() { // mark that all traits should be sent next time _shouldPerformInitialSend = true; + + // reset the trait statuses + _traitStatuses.reset(); + + // pre-fill the instanced statuses that we will need to send next frame + _owningAvatar->prepareResetTraitInstances(); } void ClientTraitsHandler::sendChangedTraitsToMixer() { From 20912349a4f0b8854bda467ee1e1bd04d9bb67ef Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 30 Aug 2018 12:59:28 -0700 Subject: [PATCH 203/545] cycle avatar entity IDs for new avatar mixer --- interface/src/Application.cpp | 1 - .../src/avatars-renderer/Avatar.cpp | 1 - libraries/avatars/src/AvatarData.cpp | 10 ++++++++-- libraries/avatars/src/AvatarData.h | 3 ++- libraries/avatars/src/AvatarTraits.h | 2 +- libraries/avatars/src/ClientTraitsHandler.cpp | 20 ++++++++++++++++++- libraries/avatars/src/ClientTraitsHandler.h | 8 ++++++-- 7 files changed, 36 insertions(+), 9 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6e57311306..2a7abfa2da 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -6366,7 +6366,6 @@ void Application::clearDomainOctreeDetails() { } void Application::clearDomainAvatars() { - getMyAvatar()->setAvatarEntityDataChanged(true); // to recreate worn entities DependencyManager::get()->clearOtherAvatars(); } diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index a9af3b7725..4ffccefe61 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -139,7 +139,6 @@ Avatar::~Avatar() { } }); } - auto geometryCache = DependencyManager::get(); if (geometryCache) { geometryCache->releaseID(_nameRectGeometryID); diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index ea6dbd7074..e7aaa18576 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -1861,7 +1861,9 @@ qint64 AvatarData::packTrait(AvatarTraits::TraitType traitType, ExtendedIODevice } qint64 AvatarData::packTraitInstance(AvatarTraits::TraitType traitType, AvatarTraits::TraitInstanceID traitInstanceID, - ExtendedIODevice& destination, AvatarTraits::TraitVersion traitVersion) { + ExtendedIODevice& destination, AvatarTraits::TraitVersion traitVersion, + AvatarTraits::TraitInstanceID wireInstanceID) { + qint64 bytesWritten = 0; bytesWritten += destination.writePrimitive(traitType); @@ -1870,7 +1872,11 @@ qint64 AvatarData::packTraitInstance(AvatarTraits::TraitType traitType, AvatarTr bytesWritten += destination.writePrimitive(traitVersion); } - bytesWritten += destination.write(traitInstanceID.toRfc4122()); + if (!wireInstanceID.isNull()) { + bytesWritten += destination.write(wireInstanceID.toRfc4122()); + } else { + bytesWritten += destination.write(traitInstanceID.toRfc4122()); + } if (traitType == AvatarTraits::AvatarEntity) { // grab a read lock on the avatar entities and check for entity data for the given ID diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index db2b82b0b7..b010a9f924 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -962,7 +962,8 @@ public: qint64 packTrait(AvatarTraits::TraitType traitType, ExtendedIODevice& destination, AvatarTraits::TraitVersion traitVersion = AvatarTraits::NULL_TRAIT_VERSION); qint64 packTraitInstance(AvatarTraits::TraitType traitType, AvatarTraits::TraitInstanceID instanceID, - ExtendedIODevice& destination, AvatarTraits::TraitVersion traitVersion = AvatarTraits::NULL_TRAIT_VERSION); + ExtendedIODevice& destination, AvatarTraits::TraitVersion traitVersion = AvatarTraits::NULL_TRAIT_VERSION, + AvatarTraits::TraitInstanceID wireInstanceID = AvatarTraits::TraitInstanceID()); void prepareResetTraitInstances(); diff --git a/libraries/avatars/src/AvatarTraits.h b/libraries/avatars/src/AvatarTraits.h index f0c807a432..5866caf234 100644 --- a/libraries/avatars/src/AvatarTraits.h +++ b/libraries/avatars/src/AvatarTraits.h @@ -41,7 +41,7 @@ namespace AvatarTraits { const TraitWireSize DELETED_TRAIT_SIZE = -1; inline qint64 packInstancedTraitDelete(TraitType traitType, TraitInstanceID instanceID, ExtendedIODevice& destination, - TraitVersion traitVersion = NULL_TRAIT_VERSION) { + TraitVersion traitVersion = NULL_TRAIT_VERSION) { qint64 bytesWritten = 0; bytesWritten += destination.writePrimitive(traitType); diff --git a/libraries/avatars/src/ClientTraitsHandler.cpp b/libraries/avatars/src/ClientTraitsHandler.cpp index a06b53da7c..94823610dc 100644 --- a/libraries/avatars/src/ClientTraitsHandler.cpp +++ b/libraries/avatars/src/ClientTraitsHandler.cpp @@ -43,6 +43,9 @@ void ClientTraitsHandler::resetForNewMixer() { // pre-fill the instanced statuses that we will need to send next frame _owningAvatar->prepareResetTraitInstances(); + + // reset the trait XOR ID since we're resetting for a new avatar mixer + _sessionXORID = QUuid::createUuid().toRfc4122(); } void ClientTraitsHandler::sendChangedTraitsToMixer() { @@ -93,7 +96,11 @@ void ClientTraitsHandler::sendChangedTraitsToMixer() { || instanceIDValuePair.value == Updated) { // this is a changed trait we need to send or we haven't send out trait information yet // ask the owning avatar to pack it - _owningAvatar->packTraitInstance(instancedIt->traitType, instanceIDValuePair.id, *traitsPacketList); + + // since this is going to the mixer, use the XORed instance ID (to anonymize trait instance IDs + // that would typically persist across sessions) + _owningAvatar->packTraitInstance(instancedIt->traitType, instanceIDValuePair.id, *traitsPacketList, + AvatarTraits::NULL_TRAIT_VERSION, xorInstanceID(instanceIDValuePair.id)); } else if (!_shouldPerformInitialSend && instanceIDValuePair.value == Deleted) { // pack delete for this trait instance AvatarTraits::packInstancedTraitDelete(instancedIt->traitType, instanceIDValuePair.id, @@ -111,6 +118,17 @@ void ClientTraitsHandler::sendChangedTraitsToMixer() { } } +AvatarTraits::TraitInstanceID ClientTraitsHandler::xorInstanceID(AvatarTraits::TraitInstanceID localInstanceID) { + QByteArray xorInstanceID { NUM_BYTES_RFC4122_UUID, 0 }; + auto localInstanceIDBytes = localInstanceID.toRfc4122(); + + for (auto i = 0; i < localInstanceIDBytes.size(); ++i) { + xorInstanceID[i] = localInstanceIDBytes[i] ^ _sessionXORID[i]; + } + + return QUuid::fromRfc4122(xorInstanceID); +} + void ClientTraitsHandler::processTraitOverride(QSharedPointer message, SharedNodePointer sendingNode) { if (sendingNode->getType() == NodeType::AvatarMixer) { while (message->getBytesLeftToRead()) { diff --git a/libraries/avatars/src/ClientTraitsHandler.h b/libraries/avatars/src/ClientTraitsHandler.h index 27ba58d46b..2319061502 100644 --- a/libraries/avatars/src/ClientTraitsHandler.h +++ b/libraries/avatars/src/ClientTraitsHandler.h @@ -30,13 +30,15 @@ public: void markTraitUpdated(AvatarTraits::TraitType updatedTrait) { _traitStatuses[updatedTrait] = Updated; _hasChangedTraits = true; } - void markInstancedTraitUpdated(AvatarTraits::TraitType traitType, QUuid updatedInstanceID) + void markInstancedTraitUpdated(AvatarTraits::TraitType traitType, AvatarTraits::TraitInstanceID updatedInstanceID) { _traitStatuses.instanceInsert(traitType, updatedInstanceID, Updated); _hasChangedTraits = true; } - void markInstancedTraitDeleted(AvatarTraits::TraitType traitType, QUuid deleteInstanceID) + void markInstancedTraitDeleted(AvatarTraits::TraitType traitType, AvatarTraits::TraitInstanceID deleteInstanceID) { _traitStatuses.instanceInsert(traitType, deleteInstanceID, Deleted); _hasChangedTraits = true; } void resetForNewMixer(); + AvatarTraits::TraitInstanceID xorInstanceID(AvatarTraits::TraitInstanceID localInstanceID); + public slots: void processTraitOverride(QSharedPointer message, SharedNodePointer sendingNode); @@ -53,6 +55,8 @@ private: AvatarTraits::TraitVersion _currentTraitVersion { AvatarTraits::DEFAULT_TRAIT_VERSION }; AvatarTraits::TraitVersion _currentSkeletonVersion { AvatarTraits::NULL_TRAIT_VERSION }; + + QByteArray _sessionXORID { NUM_BYTES_RFC4122_UUID, 0}; bool _shouldPerformInitialSend { false }; bool _hasChangedTraits { false }; From 9b3d9dd0f319ad2964e54a72bd17934765a91c02 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 31 Aug 2018 16:31:33 -0700 Subject: [PATCH 204/545] XOR incoming trait instance IDs for other avatars --- libraries/avatars/src/AvatarData.h | 5 +++++ libraries/avatars/src/AvatarHashMap.cpp | 20 ++++++++++++++---- libraries/avatars/src/AvatarTraits.h | 21 +++++++++++++++++-- libraries/avatars/src/ClientTraitsHandler.cpp | 21 +++++++------------ libraries/avatars/src/ClientTraitsHandler.h | 4 ---- 5 files changed, 47 insertions(+), 24 deletions(-) diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index b010a9f924..e9f1f5f6c3 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -1193,6 +1193,9 @@ public: void setReplicaIndex(int replicaIndex) { _replicaIndex = replicaIndex; } int getReplicaIndex() { return _replicaIndex; } + const AvatarTraits::TraitInstanceID getTraitInstanceXORID() const { return _traitInstanceXORID; } + void cycleTraitInstanceXORID() { _traitInstanceXORID = QUuid::createUuid(); } + signals: /**jsdoc @@ -1499,6 +1502,8 @@ private: // privatize the copy constructor and assignment operator so they cannot be called AvatarData(const AvatarData&); AvatarData& operator= (const AvatarData&); + + AvatarTraits::TraitInstanceID _traitInstanceXORID { QUuid::createUuid() }; }; Q_DECLARE_METATYPE(AvatarData*) diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index c437b56f32..fac2af9ebc 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -335,17 +335,29 @@ void AvatarHashMap::processBulkAvatarTraits(QSharedPointer mess AvatarTraits::TraitInstanceID traitInstanceID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); + // XOR the incoming trait instance ID with this avatar object's personal XOR ID + + // this ensures that we have separate entity instances in the local tree + // if we briefly end up with two Avatar objects for this node + + // (which can occur if the shared pointer for the + // previous instance of an avatar hasn't yet gone out of scope before the + // new instance is created) + + auto xoredInstanceID = AvatarTraits::xoredInstanceID(traitInstanceID, avatar->getTraitInstanceXORID()); + message->readPrimitive(&traitBinarySize); auto& processedInstanceVersion = lastProcessedVersions.getInstanceValueRef(traitType, traitInstanceID); if (packetTraitVersion > processedInstanceVersion) { + // in order to handle re-connections to the avatar mixer when the other if (traitBinarySize == AvatarTraits::DELETED_TRAIT_SIZE) { - avatar->processDeletedTraitInstance(traitType, traitInstanceID); - _replicas.processDeletedTraitInstance(avatarID, traitType, traitInstanceID); + avatar->processDeletedTraitInstance(traitType, xoredInstanceID); + _replicas.processDeletedTraitInstance(avatarID, traitType, xoredInstanceID); } else { auto traitData = message->read(traitBinarySize); - avatar->processTraitInstance(traitType, traitInstanceID, traitData); - _replicas.processTraitInstance(avatarID, traitType, traitInstanceID, traitData); + avatar->processTraitInstance(traitType, xoredInstanceID, traitData); + _replicas.processTraitInstance(avatarID, traitType, xoredInstanceID, traitData); } processedInstanceVersion = packetTraitVersion; } else { diff --git a/libraries/avatars/src/AvatarTraits.h b/libraries/avatars/src/AvatarTraits.h index 5866caf234..47be0d6111 100644 --- a/libraries/avatars/src/AvatarTraits.h +++ b/libraries/avatars/src/AvatarTraits.h @@ -41,7 +41,8 @@ namespace AvatarTraits { const TraitWireSize DELETED_TRAIT_SIZE = -1; inline qint64 packInstancedTraitDelete(TraitType traitType, TraitInstanceID instanceID, ExtendedIODevice& destination, - TraitVersion traitVersion = NULL_TRAIT_VERSION) { + TraitVersion traitVersion = NULL_TRAIT_VERSION, + TraitInstanceID xoredInstanceID = TraitInstanceID()) { qint64 bytesWritten = 0; bytesWritten += destination.writePrimitive(traitType); @@ -50,12 +51,28 @@ namespace AvatarTraits { bytesWritten += destination.writePrimitive(traitVersion); } - bytesWritten += destination.write(instanceID.toRfc4122()); + if (xoredInstanceID.isNull()) { + bytesWritten += destination.write(instanceID.toRfc4122()); + } else { + bytesWritten += destination.write(xoredInstanceID.toRfc4122()); + } bytesWritten += destination.writePrimitive(DELETED_TRAIT_SIZE); return bytesWritten; } + + inline TraitInstanceID xoredInstanceID(TraitInstanceID localInstanceID, TraitInstanceID xorKeyID) { + QByteArray xoredInstanceID { NUM_BYTES_RFC4122_UUID, 0 }; + auto xorKeyIDBytes = xorKeyID.toRfc4122(); + auto localInstanceIDBytes = localInstanceID.toRfc4122(); + + for (auto i = 0; i < localInstanceIDBytes.size(); ++i) { + xoredInstanceID[i] = localInstanceIDBytes[i] ^ xorKeyIDBytes[i]; + } + + return QUuid::fromRfc4122(xoredInstanceID); + } }; #endif // hifi_AvatarTraits_h diff --git a/libraries/avatars/src/ClientTraitsHandler.cpp b/libraries/avatars/src/ClientTraitsHandler.cpp index 94823610dc..479852cf9a 100644 --- a/libraries/avatars/src/ClientTraitsHandler.cpp +++ b/libraries/avatars/src/ClientTraitsHandler.cpp @@ -45,7 +45,7 @@ void ClientTraitsHandler::resetForNewMixer() { _owningAvatar->prepareResetTraitInstances(); // reset the trait XOR ID since we're resetting for a new avatar mixer - _sessionXORID = QUuid::createUuid().toRfc4122(); + _owningAvatar->cycleTraitInstanceXORID(); } void ClientTraitsHandler::sendChangedTraitsToMixer() { @@ -100,11 +100,15 @@ void ClientTraitsHandler::sendChangedTraitsToMixer() { // since this is going to the mixer, use the XORed instance ID (to anonymize trait instance IDs // that would typically persist across sessions) _owningAvatar->packTraitInstance(instancedIt->traitType, instanceIDValuePair.id, *traitsPacketList, - AvatarTraits::NULL_TRAIT_VERSION, xorInstanceID(instanceIDValuePair.id)); + AvatarTraits::NULL_TRAIT_VERSION, + AvatarTraits::xoredInstanceID(instanceIDValuePair.id, + _owningAvatar->getTraitInstanceXORID())); } else if (!_shouldPerformInitialSend && instanceIDValuePair.value == Deleted) { // pack delete for this trait instance AvatarTraits::packInstancedTraitDelete(instancedIt->traitType, instanceIDValuePair.id, - *traitsPacketList); + *traitsPacketList, AvatarTraits::NULL_TRAIT_VERSION, + AvatarTraits::xoredInstanceID(instanceIDValuePair.id, + _owningAvatar->getTraitInstanceXORID())); } } @@ -118,17 +122,6 @@ void ClientTraitsHandler::sendChangedTraitsToMixer() { } } -AvatarTraits::TraitInstanceID ClientTraitsHandler::xorInstanceID(AvatarTraits::TraitInstanceID localInstanceID) { - QByteArray xorInstanceID { NUM_BYTES_RFC4122_UUID, 0 }; - auto localInstanceIDBytes = localInstanceID.toRfc4122(); - - for (auto i = 0; i < localInstanceIDBytes.size(); ++i) { - xorInstanceID[i] = localInstanceIDBytes[i] ^ _sessionXORID[i]; - } - - return QUuid::fromRfc4122(xorInstanceID); -} - void ClientTraitsHandler::processTraitOverride(QSharedPointer message, SharedNodePointer sendingNode) { if (sendingNode->getType() == NodeType::AvatarMixer) { while (message->getBytesLeftToRead()) { diff --git a/libraries/avatars/src/ClientTraitsHandler.h b/libraries/avatars/src/ClientTraitsHandler.h index 2319061502..6d1592ba74 100644 --- a/libraries/avatars/src/ClientTraitsHandler.h +++ b/libraries/avatars/src/ClientTraitsHandler.h @@ -37,8 +37,6 @@ public: void resetForNewMixer(); - AvatarTraits::TraitInstanceID xorInstanceID(AvatarTraits::TraitInstanceID localInstanceID); - public slots: void processTraitOverride(QSharedPointer message, SharedNodePointer sendingNode); @@ -55,8 +53,6 @@ private: AvatarTraits::TraitVersion _currentTraitVersion { AvatarTraits::DEFAULT_TRAIT_VERSION }; AvatarTraits::TraitVersion _currentSkeletonVersion { AvatarTraits::NULL_TRAIT_VERSION }; - - QByteArray _sessionXORID { NUM_BYTES_RFC4122_UUID, 0}; bool _shouldPerformInitialSend { false }; bool _hasChangedTraits { false }; From a37a19da1e4e7657548fb29ad6cf4e130a5eda76 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 31 Aug 2018 16:59:24 -0700 Subject: [PATCH 205/545] use different XORed instance ID for replicas --- libraries/avatars/src/AvatarHashMap.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index fac2af9ebc..c1246866dc 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -85,7 +85,8 @@ void AvatarReplicas::processDeletedTraitInstance(const QUuid& parentID, AvatarTr if (_replicasMap.find(parentID) != _replicasMap.end()) { auto &replicas = _replicasMap[parentID]; for (auto avatar : replicas) { - avatar->processDeletedTraitInstance(traitType, instanceID); + avatar->processDeletedTraitInstance(traitType, + AvatarTraits::xoredInstanceID(instanceID, avatar->getTraitInstanceXORID())); } } } @@ -94,7 +95,9 @@ void AvatarReplicas::processTraitInstance(const QUuid& parentID, AvatarTraits::T if (_replicasMap.find(parentID) != _replicasMap.end()) { auto &replicas = _replicasMap[parentID]; for (auto avatar : replicas) { - avatar->processTraitInstance(traitType, instanceID, traitBinaryData); + avatar->processTraitInstance(traitType, + AvatarTraits::xoredInstanceID(instanceID, avatar->getTraitInstanceXORID()), + traitBinaryData); } } } @@ -353,11 +356,11 @@ void AvatarHashMap::processBulkAvatarTraits(QSharedPointer mess // in order to handle re-connections to the avatar mixer when the other if (traitBinarySize == AvatarTraits::DELETED_TRAIT_SIZE) { avatar->processDeletedTraitInstance(traitType, xoredInstanceID); - _replicas.processDeletedTraitInstance(avatarID, traitType, xoredInstanceID); + _replicas.processDeletedTraitInstance(avatarID, traitType, traitInstanceID); } else { auto traitData = message->read(traitBinarySize); avatar->processTraitInstance(traitType, xoredInstanceID, traitData); - _replicas.processTraitInstance(avatarID, traitType, xoredInstanceID, traitData); + _replicas.processTraitInstance(avatarID, traitType, traitInstanceID, traitData); } processedInstanceVersion = packetTraitVersion; } else { From cf5f81ab95da956565f1d6035f1e38cec12bc48d Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Fri, 31 Aug 2018 17:04:23 -0700 Subject: [PATCH 206/545] Don't memcpy quaternions as we don't use same component order on wire! --- libraries/avatars/src/AvatarData.cpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index c7a506a782..d60a1a1310 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -666,6 +666,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent destinationBuffer += packOrientationQuatToSixBytes(destinationBuffer, controllerLeftHandTransform.getRotation()); destinationBuffer += packFloatVec3ToSignedTwoByteFixed(destinationBuffer, controllerLeftHandTransform.getTranslation(), TRANSLATION_COMPRESSION_RADIX); + Transform controllerRightHandTransform = Transform(getControllerRightHandMatrix()); destinationBuffer += packOrientationQuatToSixBytes(destinationBuffer, controllerRightHandTransform.getRotation()); destinationBuffer += packFloatVec3ToSignedTwoByteFixed(destinationBuffer, controllerRightHandTransform.getTranslation(), @@ -674,6 +675,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent if (hasGrabJoints) { // the far-grab joints may range further than 3 meters, so we can't use packFloatVec3ToSignedTwoByteFixed etc auto startSection = destinationBuffer; + auto data = reinterpret_cast(destinationBuffer); glm::vec3 leftFarGrabPosition = extractTranslation(leftFarGrabMatrix); glm::quat leftFarGrabRotation = extractRotation(leftFarGrabMatrix); glm::vec3 rightFarGrabPosition = extractTranslation(rightFarGrabMatrix); @@ -682,11 +684,25 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent glm::quat mouseFarGrabRotation = extractRotation(mouseFarGrabMatrix); AVATAR_MEMCPY(leftFarGrabPosition); - AVATAR_MEMCPY(leftFarGrabRotation); + data->leftFarGrabRotation[0] = leftFarGrabRotation.w; + data->leftFarGrabRotation[1] = leftFarGrabRotation.x; + data->leftFarGrabRotation[2] = leftFarGrabRotation.y; + data->leftFarGrabRotation[3] = leftFarGrabRotation.z; + destinationBuffer += sizeof(data->leftFarGrabPosition); + AVATAR_MEMCPY(rightFarGrabPosition); - AVATAR_MEMCPY(rightFarGrabRotation); + data->rightFarGrabRotation[0] = rightFarGrabRotation.w; + data->rightFarGrabRotation[1] = rightFarGrabRotation.x; + data->rightFarGrabRotation[2] = rightFarGrabRotation.y; + data->rightFarGrabRotation[3] = rightFarGrabRotation.z; + destinationBuffer += sizeof(data->rightFarGrabRotation); + AVATAR_MEMCPY(mouseFarGrabPosition); - AVATAR_MEMCPY(mouseFarGrabRotation); + data->mouseFarGrabRotation[0] = mouseFarGrabRotation.w; + data->mouseFarGrabRotation[1] = mouseFarGrabRotation.x; + data->mouseFarGrabRotation[2] = mouseFarGrabRotation.y; + data->mouseFarGrabRotation[3] = mouseFarGrabRotation.z; + destinationBuffer += sizeof(data->mouseFarGrabRotation); int numBytes = destinationBuffer - startSection; From 11a563cb386290c254040e4a5a0f1a79326af3e2 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Fri, 31 Aug 2018 17:40:57 -0700 Subject: [PATCH 207/545] Don't use temp vector for outgoing joint status - doesn't seem to be necessary --- libraries/avatars/src/AvatarData.cpp | 34 ++++++++-------------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index d60a1a1310..ed1a8e5742 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -573,10 +573,8 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent destinationBuffer += numValidityBytes; // Move pointer past the validity bytes // sentJointDataOut and lastSentJointData might be the same vector - // build sentJointDataOut locally and then swap it at the end. - QVector localSentJointDataOut; if (sentJointDataOut) { - localSentJointDataOut.resize(numJoints); // Make sure the destination is resized before using it + sentJointDataOut->resize(numJoints); // Make sure the destination is resized before using it } float minRotationDOT = (distanceAdjust && cullSmallChanges) ? getDistanceBasedMinRotationDOT(viewerPosition) : AVATAR_MIN_ROTATION_DOT; @@ -597,11 +595,13 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent destinationBuffer += packOrientationQuatToSixBytes(destinationBuffer, data.rotation); if (sentJointDataOut) { - localSentJointDataOut[i].rotation = data.rotation; - localSentJointDataOut[i].rotationIsDefaultPose = false; + (*sentJointDataOut)[i].rotation = data.rotation; } } } + + (*sentJointDataOut)[i].rotationIsDefaultPose = data.rotationIsDefaultPose; + if (++validityBit == BITS_IN_BYTE) { *validityPosition++ = validity; validityBit = validity = 0; @@ -646,11 +646,13 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent packFloatVec3ToSignedTwoByteFixed(destinationBuffer, data.translation, TRANSLATION_COMPRESSION_RADIX); if (sentJointDataOut) { - localSentJointDataOut[i].translation = data.translation; - localSentJointDataOut[i].translationIsDefaultPose = false; + (*sentJointDataOut)[i].translation = data.translation; } } } + + (*sentJointDataOut)[i].translationIsDefaultPose = data.translationIsDefaultPose; + if (++validityBit == BITS_IN_BYTE) { *validityPosition++ = validity; validityBit = validity = 0; @@ -729,24 +731,6 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent outboundDataRateOut->jointDataRate.increment(numBytes); } - if (sentJointDataOut) { - - // Mark default poses in lastSentJointData, so when they become non-default we send them. - for (int i = 0; i < jointData.size(); i++) { - const JointData& data = jointData[i]; - JointData& local = localSentJointDataOut[i]; - if (data.rotationIsDefaultPose) { - local.rotationIsDefaultPose = true; - } - if (data.translationIsDefaultPose) { - local.translationIsDefaultPose = true; - } - } - - // Push new sent joint data to sentJointDataOut - sentJointDataOut->swap(localSentJointDataOut); - } - // Always true, currently: if (hasJointDefaultPoseFlags) { auto startSection = destinationBuffer; From c95cb97b9bbf29e69971a8fb3faa8dcd89f5295d Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Fri, 31 Aug 2018 19:29:48 -0700 Subject: [PATCH 208/545] adding working version with networking signals --- interface/resources/serverless/redirect.json | 1609 +++++++++--------- interface/src/Application.cpp | 31 +- interface/src/Application.h | 4 +- libraries/networking/src/AddressManager.cpp | 44 +- libraries/networking/src/AddressManager.h | 12 +- libraries/networking/src/DomainHandler.cpp | 21 +- libraries/networking/src/DomainHandler.h | 4 +- 7 files changed, 891 insertions(+), 834 deletions(-) diff --git a/interface/resources/serverless/redirect.json b/interface/resources/serverless/redirect.json index 71dfae4212..fd81b6d433 100644 --- a/interface/resources/serverless/redirect.json +++ b/interface/resources/serverless/redirect.json @@ -5,91 +5,91 @@ "clientOnly": false, "collidesWith": "static,dynamic,kinematic,otherAvatar,", "collisionMask": 23, - "created": "2018-08-29T22:59:44Z", + "created": "2018-08-31T21:40:18Z", "dimensions": { - "blue": 0.26190000772476196, - "green": 0.5595999956130981, - "red": 0.5318999886512756, - "x": 0.5318999886512756, - "y": 0.5595999956130981, - "z": 0.26190000772476196 + "blue": 0.8231174349784851, + "green": 1.8264780044555664, + "red": 1.2112245559692383, + "x": 1.2112245559692383, + "y": 1.8264780044555664, + "z": 0.8231174349784851 }, - "id": "{4782f05d-ca51-41d4-9d19-21b8cad5ec2d}", - "lastEdited": 1535584079688600, - "lastEditedBy": "{f5457c14-32ca-45c2-9dde-4f5b30b3be1b}", - "name": "Try Again Box", + "id": "{1a8bf6e0-6f03-4761-9aba-1f624fae1236}", + "lastEdited": 1535751992686833, + "lastEditedBy": "{ace8f357-ad94-49e1-b4d0-39c4d5a936f3}", + "name": "Try Again Zone", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": { - "blue": 4.54052734375, - "green": 1.722428798675537, - "red": 4.593362331390381, - "x": 0.5933623313903809, - "y": -7.777571201324463, - "z": 0.54052734375 + "blue": 4.442525863647461, + "green": 1.9289360046386719, + "red": 2.600449562072754, + "x": -1.399550437927246, + "y": -7.571063995361328, + "z": 0.44252586364746094 }, "queryAACube": { - "scale": 0.8152676820755005, - "x": 4.185728549957275, - "y": 1.3147950172424316, - "z": 4.1328935623168945 + "scale": 2.3410699367523193, + "x": 1.4299145936965942, + "y": 0.7584010362625122, + "z": 3.2719907760620117 }, "rotation": { - "w": 0.9868703484535217, - "x": -0.010178769007325172, - "y": -0.15702557563781738, - "z": 0.03642075136303902 - }, - "script": "file:///C:/Users/wayne/development/tryAgainBoxEntityScript.js", - "shape": "Cube", - "type": "Box", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}", - "visible": false - }, - { - "clientOnly": false, - "created": "2018-08-29T23:01:55Z", - "dimensions": { - "blue": 0.26190000772476196, - "green": 0.5595999956130981, - "red": 0.5318999886512756, - "x": 0.5318999886512756, - "y": 0.5595999956130981, - "z": 0.26190000772476196 - }, - "id": "{8c9287c8-3826-4f2e-944e-05d8d4715fb8}", - "lastEdited": 1535584095676575, - "lastEditedBy": "{f5457c14-32ca-45c2-9dde-4f5b30b3be1b}", - "name": "Back Box", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 3.9590959548950195, - "green": 1.738053798675537, - "red": 5.0181121826171875, - "x": 1.0181121826171875, - "y": -7.761946201324463, - "z": -0.04090404510498047 - }, - "queryAACube": { - "scale": 0.8152676820755005, - "x": 4.610478401184082, - "y": 1.3304200172424316, - "z": 3.551462173461914 - }, - "rotation": { - "w": 0.9366722106933594, + "w": 0.9743700623512268, "x": 0, - "y": -0.3502073884010315, + "y": -0.22495104372501373, "z": 0 }, - "script": "file:///C:/Users/wayne/development/backBoxEntityScript.js", - "shape": "Cube", - "type": "Box", - "userData": "{\"grabbableKey\":{\"grabbable\":true}}", - "visible": false + "script": "file:///C:/Users/wayne/development/zoneTryAgainEntityScript.js", + "shapeType": "box", + "type": "Zone", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}" }, { "clientOnly": false, - "created": "2018-08-29T22:57:33Z", + "collidesWith": "static,dynamic,kinematic,otherAvatar,", + "collisionMask": 23, + "created": "2018-08-31T21:44:40Z", + "dimensions": { + "blue": 0.7544999718666077, + "green": 1.8265000581741333, + "red": 1.0555000305175781, + "x": 1.0555000305175781, + "y": 1.8265000581741333, + "z": 0.7544999718666077 + }, + "id": "{eb439982-948a-4393-8e8c-fdd833e6d9a7}", + "lastEdited": 1535752005525769, + "lastEditedBy": "{ace8f357-ad94-49e1-b4d0-39c4d5a936f3}", + "name": "Back Zone", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 2.538674831390381, + "green": 1.8022732734680176, + "red": 3.5101304054260254, + "x": -0.4898695945739746, + "y": -7.697726726531982, + "z": -1.4613251686096191 + }, + "queryAACube": { + "scale": 2.2404136657714844, + "x": 2.389923572540283, + "y": 0.6820664405822754, + "z": 1.4184679985046387 + }, + "rotation": { + "w": 0.9304176568984985, + "x": 0, + "y": -0.36650121212005615, + "z": 0 + }, + "script": "file:///C:/Users/wayne/development/zoneBackEntityScript.js", + "shapeType": "box", + "type": "Zone", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}" + }, + { + "clientOnly": false, + "created": "2018-08-31T21:35:56Z", "dimensions": { "blue": 14.40000057220459, "green": 14.40000057220459, @@ -98,9 +98,9 @@ "y": 14.40000057220459, "z": 14.40000057220459 }, - "id": "{8e6bd656-d764-4724-a89d-7b4ff96abf8a}", - "lastEdited": 1535583477860044, - "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "id": "{dbae0b3a-a7ff-4eb1-9177-fd1f20b3cec8}", + "lastEdited": 1535751789461074, + "lastEditedBy": "{ace8f357-ad94-49e1-b4d0-39c4d5a936f3}", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": { "blue": 2.3440732955932617, @@ -127,6 +127,239 @@ "type": "Zone", "userData": "{\"grabbableKey\":{\"grabbable\":false}}" }, + { + "clientOnly": false, + "color": { + "blue": 0, + "green": 0, + "red": 0 + }, + "created": "2018-08-31T21:35:56Z", + "dimensions": { + "blue": 11.117486953735352, + "green": 3.580313205718994, + "red": 0.20000000298023224, + "x": 0.20000000298023224, + "y": 3.580313205718994, + "z": 11.117486953735352 + }, + "id": "{c92b026b-e13c-448a-903c-2773f9fdc2e8}", + "lastEdited": 1535751961512543, + "lastEditedBy": "{ace8f357-ad94-49e1-b4d0-39c4d5a936f3}", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 1.9063844680786133, + "green": 1.15850830078125, + "red": 0.16632509231567383, + "x": -3.833674907684326, + "y": -8.34149169921875, + "z": -2.0936155319213867 + }, + "queryAACube": { + "scale": 11.681488037109375, + "x": -5.674418926239014, + "y": -4.6822357177734375, + "z": -3.934359550476074 + }, + "rotation": { + "w": 0.9666743278503418, + "x": -4.57763671875e-05, + "y": -0.2560006380081177, + "z": 1.52587890625e-05 + }, + "shape": "Cube", + "type": "Box", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}", + "visible": false + }, + { + "clientOnly": false, + "color": { + "blue": 0, + "green": 0, + "red": 0 + }, + "created": "2018-08-31T21:35:56Z", + "dimensions": { + "blue": 11.117486953735352, + "green": 3.580313205718994, + "red": 0.20000000298023224, + "x": 0.20000000298023224, + "y": 3.580313205718994, + "z": 11.117486953735352 + }, + "id": "{cd72debb-75a6-420d-b39f-b903fb069798}", + "lastEdited": 1535751362199714, + "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 6.1806135177612305, + "green": 1.1588134765625, + "red": 1.4755167961120605, + "x": -2.5244832038879395, + "y": -8.3411865234375, + "z": 2.1806135177612305 + }, + "queryAACube": { + "scale": 11.681488037109375, + "x": -4.365227222442627, + "y": -4.6819305419921875, + "z": 0.33986949920654297 + }, + "rotation": { + "w": 0.8637980222702026, + "x": -4.57763671875e-05, + "y": 0.5038070678710938, + "z": -1.52587890625e-05 + }, + "shape": "Cube", + "type": "Box", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}", + "visible": false + }, + { + "clientOnly": false, + "color": { + "blue": 0, + "green": 0, + "red": 0 + }, + "created": "2018-08-31T21:35:56Z", + "dimensions": { + "blue": 11.117486953735352, + "green": 3.580313205718994, + "red": 0.20000000298023224, + "x": 0.20000000298023224, + "y": 3.580313205718994, + "z": 11.117486953735352 + }, + "id": "{abe300d5-32b8-4d0c-bf82-e78005b79b70}", + "lastEdited": 1535751362199153, + "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 5.268576622009277, + "green": 1.1588134765625, + "red": 6.100250244140625, + "x": 2.100250244140625, + "y": -8.3411865234375, + "z": 1.2685766220092773 + }, + "queryAACube": { + "scale": 11.681488037109375, + "x": 0.2595062255859375, + "y": -4.6819305419921875, + "z": -0.5721673965454102 + }, + "rotation": { + "w": 0.9662165641784668, + "x": -4.57763671875e-05, + "y": -0.2576791048049927, + "z": 1.52587890625e-05 + }, + "shape": "Cube", + "type": "Box", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}", + "visible": false + }, + { + "angularDamping": 0, + "clientOnly": false, + "color": { + "blue": 0, + "green": 0, + "red": 255 + }, + "created": "2018-08-31T21:35:56Z", + "dimensions": { + "blue": 0.20000000298023224, + "green": 0.20000000298023224, + "red": 0.20000000298023224, + "x": 0.20000000298023224, + "y": 0.20000000298023224, + "z": 0.20000000298023224 + }, + "id": "{66757fda-b7ad-4858-83ab-724b01710cc2}", + "lastEdited": 1535751362198937, + "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "name": "Particle Rotate", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 1.3116319179534912, + "green": 0.15618896484375, + "red": 2.705613613128662, + "x": -1.294386386871338, + "y": -9.34381103515625, + "z": -2.688368082046509 + }, + "queryAACube": { + "scale": 0.3464101552963257, + "x": 2.5324084758758545, + "y": -0.017016112804412842, + "z": 1.1384267807006836 + }, + "rotation": { + "w": 0.46953535079956055, + "x": -0.16719311475753784, + "y": -0.7982757091522217, + "z": 0.3380941152572632 + }, + "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", + "scriptTimestamp": 1532724769253, + "shape": "Cube", + "type": "Box", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}", + "visible": false + }, + { + "angularDamping": 0, + "clientOnly": false, + "color": { + "blue": 0, + "green": 0, + "red": 255 + }, + "created": "2018-08-31T21:35:56Z", + "dimensions": { + "blue": 0.20000000298023224, + "green": 0.20000000298023224, + "red": 0.20000000298023224, + "x": 0.20000000298023224, + "y": 0.20000000298023224, + "z": 0.20000000298023224 + }, + "id": "{24eda146-92f8-4e43-b084-fb555626427b}", + "lastEdited": 1535751362198263, + "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "name": "Particle Rotate", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 1.3116319179534912, + "green": 0, + "red": 2.705613613128662, + "x": -1.294386386871338, + "y": -9.5, + "z": -2.688368082046509 + }, + "queryAACube": { + "scale": 0.3464101552963257, + "x": 2.5324084758758545, + "y": -0.17320507764816284, + "z": 1.1384267807006836 + }, + "rotation": { + "w": 0.9127794504165649, + "x": 0.2575265169143677, + "y": 0.15553522109985352, + "z": 0.2761729955673218 + }, + "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", + "scriptTimestamp": 1532724769253, + "shape": "Cube", + "type": "Box", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}", + "visible": false + }, { "alpha": 0, "alphaFinish": 0, @@ -148,7 +381,7 @@ "y": 255, "z": 255 }, - "created": "2018-08-29T22:57:33Z", + "created": "2018-08-31T21:35:56Z", "dimensions": { "blue": 13.24000072479248, "green": 13.24000072479248, @@ -181,8 +414,419 @@ }, "emitRate": 6, "emitSpeed": 0, - "id": "{b5ba3aa4-2eb9-4cfd-aec7-43635511c6b7}", - "lastEdited": 1535583477861791, + "emitterShouldTrail": true, + "id": "{b9a46e3e-f982-4a46-b38d-2a38e5cc5fbc}", + "lastEdited": 1535751362199964, + "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "lifespan": 10, + "maxParticles": 10, + "name": "Stars", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "particleRadius": 0.07000000029802322, + "polarFinish": 3.1415927410125732, + "position": { + "blue": 3.78922963142395, + "green": 0.5220947265625, + "red": 1.1928560733795166, + "x": -2.8071439266204834, + "y": -8.9779052734375, + "z": -0.2107703685760498 + }, + "queryAACube": { + "scale": 22.932353973388672, + "x": -10.273321151733398, + "y": -10.944082260131836, + "z": -7.676947593688965 + }, + "radiusFinish": 0, + "radiusStart": 0, + "rotation": { + "w": 0.996429443359375, + "x": -1.52587890625e-05, + "y": -0.08442819118499756, + "z": -4.57763671875e-05 + }, + "speedSpread": 0, + "spinFinish": null, + "spinStart": null, + "textures": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/star.png", + "type": "ParticleEffect", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}" + }, + { + "clientOnly": false, + "color": { + "blue": 0, + "green": 0, + "red": 0 + }, + "created": "2018-08-31T21:35:56Z", + "dimensions": { + "blue": 11.117486953735352, + "green": 3.580313205718994, + "red": 0.20000000298023224, + "x": 0.20000000298023224, + "y": 3.580313205718994, + "z": 11.117486953735352 + }, + "id": "{e6897ca3-1c22-429f-a1b6-173ff47397a7}", + "lastEdited": 1535751362197848, + "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 0, + "green": 1.1583251953125, + "red": 4.971565246582031, + "x": 0.9715652465820312, + "y": -8.3416748046875, + "z": -4 + }, + "queryAACube": { + "scale": 11.681488037109375, + "x": -0.8691787719726562, + "y": -4.6824188232421875, + "z": -5.8407440185546875 + }, + "rotation": { + "w": 0.8637980222702026, + "x": -4.57763671875e-05, + "y": 0.5038070678710938, + "z": -1.52587890625e-05 + }, + "shape": "Cube", + "type": "Box", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}", + "visible": false + }, + { + "angularDamping": 0, + "clientOnly": false, + "color": { + "blue": 0, + "green": 0, + "red": 255 + }, + "created": "2018-08-31T21:35:56Z", + "dimensions": { + "blue": 0.20000000298023224, + "green": 0.20000000298023224, + "red": 0.20000000298023224, + "x": 0.20000000298023224, + "y": 0.20000000298023224, + "z": 0.20000000298023224 + }, + "id": "{16ca16ab-eee3-41b1-b583-159245aa2010}", + "lastEdited": 1535751362197055, + "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "name": "Particle Rotate", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 1.3116319179534912, + "green": 0.0772705078125, + "red": 2.705613613128662, + "x": -1.294386386871338, + "y": -9.4227294921875, + "z": -2.688368082046509 + }, + "queryAACube": { + "scale": 0.3464101552963257, + "x": 2.5324084758758545, + "y": -0.09593456983566284, + "z": 1.1384267807006836 + }, + "rotation": { + "w": -0.38777750730514526, + "x": -0.37337303161621094, + "y": -0.8409399390220642, + "z": 0.055222392082214355 + }, + "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", + "scriptTimestamp": 1532724769253, + "shape": "Cube", + "type": "Box", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}", + "visible": false + }, + { + "clientOnly": false, + "created": "2018-08-31T21:35:56Z", + "dimensions": { + "blue": 2.1097896099090576, + "green": 0.04847164824604988, + "red": 1.458284616470337, + "x": 1.458284616470337, + "y": 0.04847164824604988, + "z": 2.1097896099090576 + }, + "id": "{482ae172-c411-41fb-9a41-4215eef25478}", + "lastEdited": 1535751754378548, + "lastEditedBy": "{ace8f357-ad94-49e1-b4d0-39c4d5a936f3}", + "modelURL": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/portal2.fbx", + "name": "Back", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 1.5835940837860107, + "green": 0.2467041015625, + "red": 3.0345542430877686, + "x": -0.9654457569122314, + "y": -9.2532958984375, + "z": -2.4164059162139893 + }, + "queryAACube": { + "scale": 2.5651814937591553, + "x": 1.751963496208191, + "y": -1.0358866453170776, + "z": 0.3010033369064331 + }, + "rotation": { + "w": 0.9084458351135254, + "x": -1.52587890625e-05, + "y": 0.4179598093032837, + "z": -0.0001068115234375 + }, + "script": "file:///C:/Users/wayne/development/backEntityScript.js", + "scriptTimestamp": 1535751754379, + "shapeType": "static-mesh", + "type": "Model", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}" + }, + { + "clientOnly": false, + "created": "2018-08-31T21:35:56Z", + "dimensions": { + "blue": 9.030570983886719, + "green": 0.0719478651881218, + "red": 9.030570983886719, + "x": 9.030570983886719, + "y": 0.0719478651881218, + "z": 9.030570983886719 + }, + "id": "{33440bf8-f9ce-4d52-9b29-1b321e226982}", + "lastEdited": 1535751362197214, + "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "modelURL": "http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/floor.fbx", + "name": "Floor", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 4.2324604988098145, + "green": 0.17547607421875, + "red": 4.802988529205322, + "x": 0.8029885292053223, + "y": -9.32452392578125, + "z": 0.23246049880981445 + }, + "queryAACube": { + "scale": 12.771358489990234, + "x": -1.582690715789795, + "y": -6.210203170776367, + "z": -2.1532187461853027 + }, + "rotation": { + "w": 0.8648051023483276, + "x": -1.52587890625e-05, + "y": 0.5020675659179688, + "z": -4.57763671875e-05 + }, + "shapeType": "simple-hull", + "type": "Model", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}" + }, + { + "angularDamping": 0, + "clientOnly": false, + "color": { + "blue": 0, + "green": 0, + "red": 255 + }, + "created": "2018-08-31T21:35:56Z", + "dimensions": { + "blue": 0.20000000298023224, + "green": 0.20000000298023224, + "red": 0.20000000298023224, + "x": 0.20000000298023224, + "y": 0.20000000298023224, + "z": 0.20000000298023224 + }, + "id": "{7639140e-cd6f-4f86-97f7-00a19f50253e}", + "lastEdited": 1535751362198721, + "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "name": "Particle Rotate", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 3.8216662406921387, + "green": 0, + "red": 1.2409718036651611, + "x": -2.759028196334839, + "y": -9.5, + "z": -0.17833375930786133 + }, + "queryAACube": { + "scale": 0.3464101552963257, + "x": 1.0677666664123535, + "y": -0.17320507764816284, + "z": 3.648461103439331 + }, + "rotation": { + "w": 0.6444342136383057, + "x": -0.08220034837722778, + "y": -0.6649118661880493, + "z": 0.3684900999069214 + }, + "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", + "scriptTimestamp": 1532724769253, + "shape": "Cube", + "type": "Box", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}", + "visible": false + }, + { + "clientOnly": false, + "created": "2018-08-31T21:35:56Z", + "dimensions": { + "blue": 2.1097896099090576, + "green": 0.04847164824604988, + "red": 1.458284616470337, + "x": 1.458284616470337, + "y": 0.04847164824604988, + "z": 2.1097896099090576 + }, + "id": "{7755bf99-b026-490d-a682-edadd3f65701}", + "lastEdited": 1535751900322535, + "lastEditedBy": "{ace8f357-ad94-49e1-b4d0-39c4d5a936f3}", + "modelURL": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/portal1.fbx", + "name": "Try Again", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 3.946338653564453, + "green": 0.2467041015625, + "red": 1.6013128757476807, + "x": -2.3986871242523193, + "y": -9.2532958984375, + "z": -0.053661346435546875 + }, + "queryAACube": { + "scale": 2.5651814937591553, + "x": 0.318722128868103, + "y": -1.0358866453170776, + "z": 2.663747787475586 + }, + "rotation": { + "w": 0.8220492601394653, + "x": -1.52587890625e-05, + "y": 0.5693598985671997, + "z": -0.0001068115234375 + }, + "script": "file:///C:/Users/wayne/development/tryAgainEntityScript.js", + "shapeType": "static-mesh", + "type": "Model", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}" + }, + { + "angularDamping": 0, + "clientOnly": false, + "color": { + "blue": 0, + "green": 0, + "red": 255 + }, + "created": "2018-08-31T21:35:56Z", + "dimensions": { + "blue": 0.20000000298023224, + "green": 0.20000000298023224, + "red": 0.20000000298023224, + "x": 0.20000000298023224, + "y": 0.20000000298023224, + "z": 0.20000000298023224 + }, + "id": "{81207b9c-e3f2-4ee1-bb81-0e14f37e4687}", + "lastEdited": 1535751362197613, + "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "name": "Particle Rotate", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 3.8216662406921387, + "green": 0.15618896484375, + "red": 1.2409718036651611, + "x": -2.759028196334839, + "y": -9.34381103515625, + "z": -0.17833375930786133 + }, + "queryAACube": { + "scale": 0.3464101552963257, + "x": 1.0677666664123535, + "y": -0.017016112804412842, + "z": 3.648461103439331 + }, + "rotation": { + "w": 0.6747081279754639, + "x": -0.06532388925552368, + "y": -0.6342412233352661, + "z": 0.37175559997558594 + }, + "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", + "scriptTimestamp": 1532724769253, + "shape": "Cube", + "type": "Box", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}", + "visible": false + }, + { + "alpha": 0, + "alphaFinish": 0, + "alphaStart": 0.25, + "clientOnly": false, + "colorFinish": { + "blue": 0, + "green": 0, + "red": 0, + "x": 0, + "y": 0, + "z": 0 + }, + "colorStart": { + "blue": 255, + "green": 255, + "red": 255, + "x": 255, + "y": 255, + "z": 255 + }, + "created": "2018-08-31T21:35:56Z", + "dimensions": { + "blue": 13.24000072479248, + "green": 13.24000072479248, + "red": 13.24000072479248, + "x": 13.24000072479248, + "y": 13.24000072479248, + "z": 13.24000072479248 + }, + "emitAcceleration": { + "blue": 0, + "green": 0.10000000149011612, + "red": 0, + "x": 0, + "y": 0.10000000149011612, + "z": 0 + }, + "emitDimensions": { + "blue": 1, + "green": 1, + "red": 1, + "x": 1, + "y": 1, + "z": 1 + }, + "emitOrientation": { + "w": 1, + "x": -1.52587890625e-05, + "y": -1.52587890625e-05, + "z": -1.52587890625e-05 + }, + "emitRate": 6, + "emitSpeed": 0, + "id": "{b8f11bf5-410e-4e35-b4c3-91c86c01351d}", + "lastEdited": 1535751362196710, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "lifespan": 10, "maxParticles": 10, @@ -219,558 +863,6 @@ "type": "ParticleEffect", "userData": "{\"grabbableKey\":{\"grabbable\":false}}" }, - { - "clientOnly": false, - "color": { - "blue": 0, - "green": 0, - "red": 0 - }, - "created": "2018-08-29T22:57:33Z", - "dimensions": { - "blue": 11.117486953735352, - "green": 3.580313205718994, - "red": 0.20000000298023224, - "x": 0.20000000298023224, - "y": 3.580313205718994, - "z": 11.117486953735352 - }, - "id": "{12a26c55-c411-4c4c-a124-cac9c80f9532}", - "lastEdited": 1535583681180522, - "lastEditedBy": "{f5457c14-32ca-45c2-9dde-4f5b30b3be1b}", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 1.9063844680786133, - "green": 1.15850830078125, - "red": 0.16632509231567383, - "x": -3.833674907684326, - "y": -8.34149169921875, - "z": -2.0936155319213867 - }, - "queryAACube": { - "scale": 11.681488037109375, - "x": -5.674418926239014, - "y": -4.6822357177734375, - "z": -3.934359550476074 - }, - "rotation": { - "w": 0.9666743278503418, - "x": -4.57763671875e-05, - "y": -0.2560006380081177, - "z": 1.52587890625e-05 - }, - "shape": "Cube", - "type": "Box", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}", - "visible": false - }, - { - "angularDamping": 0, - "clientOnly": false, - "color": { - "blue": 0, - "green": 0, - "red": 255 - }, - "created": "2018-08-29T22:57:33Z", - "dimensions": { - "blue": 0.20000000298023224, - "green": 0.20000000298023224, - "red": 0.20000000298023224, - "x": 0.20000000298023224, - "y": 0.20000000298023224, - "z": 0.20000000298023224 - }, - "id": "{e8fd2c79-1303-49e4-8e4a-823272d6558c}", - "lastEdited": 1535583477862445, - "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", - "name": "Particle Rotate", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 1.3116319179534912, - "green": 0.0772705078125, - "red": 2.705613613128662, - "x": -1.294386386871338, - "y": -9.4227294921875, - "z": -2.688368082046509 - }, - "queryAACube": { - "scale": 0.3464101552963257, - "x": 2.5324084758758545, - "y": -0.09593456983566284, - "z": 1.1384267807006836 - }, - "rotation": { - "w": -0.38777750730514526, - "x": -0.37337303161621094, - "y": -0.8409399390220642, - "z": 0.055222392082214355 - }, - "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", - "scriptTimestamp": 1532724769253, - "shape": "Cube", - "type": "Box", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}", - "visible": false - }, - { - "clientOnly": false, - "created": "2018-08-29T22:57:33Z", - "dimensions": { - "blue": 9.030570983886719, - "green": 0.0719478651881218, - "red": 9.030570983886719, - "x": 9.030570983886719, - "y": 0.0719478651881218, - "z": 9.030570983886719 - }, - "id": "{85b4551d-c05d-4038-b188-30ad5db9c23a}", - "lastEdited": 1535583477861514, - "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", - "modelURL": "http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/floor.fbx", - "name": "Floor", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 4.2324604988098145, - "green": 0.17547607421875, - "red": 4.802988529205322, - "x": 0.8029885292053223, - "y": -9.32452392578125, - "z": 0.23246049880981445 - }, - "queryAACube": { - "scale": 12.771358489990234, - "x": -1.582690715789795, - "y": -6.210203170776367, - "z": -2.1532187461853027 - }, - "rotation": { - "w": 0.8648051023483276, - "x": -1.52587890625e-05, - "y": 0.5020675659179688, - "z": -4.57763671875e-05 - }, - "shapeType": "simple-hull", - "type": "Model", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}" - }, - { - "clientOnly": false, - "created": "2018-08-29T22:57:33Z", - "dimensions": { - "blue": 0.06014331430196762, - "green": 2.582186460494995, - "red": 2.582186698913574, - "x": 2.582186698913574, - "y": 2.582186460494995, - "z": 0.06014331430196762 - }, - "id": "{8e4d8047-c2e2-4b2c-bfa2-c732d419d59a}", - "lastEdited": 1535583477860645, - "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", - "modelURL": "http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/oopsDialog.fbx", - "name": "Oops Dialog", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 1.45927095413208, - "green": 1.6763916015625, - "red": 0, - "x": -4, - "y": -7.8236083984375, - "z": -2.54072904586792 - }, - "queryAACube": { - "scale": 3.6522583961486816, - "x": -1.8261291980743408, - "y": -0.14973759651184082, - "z": -0.36685824394226074 - }, - "rotation": { - "w": 0.8684672117233276, - "x": -4.57763671875e-05, - "y": 0.4957197904586792, - "z": -7.62939453125e-05 - }, - "type": "Model", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}" - }, - { - "angularDamping": 0, - "clientOnly": false, - "color": { - "blue": 0, - "green": 0, - "red": 255 - }, - "created": "2018-08-29T22:57:33Z", - "dimensions": { - "blue": 0.20000000298023224, - "green": 0.20000000298023224, - "red": 0.20000000298023224, - "x": 0.20000000298023224, - "y": 0.20000000298023224, - "z": 0.20000000298023224 - }, - "id": "{4fc1436d-00e7-43ec-83e1-f70cff544885}", - "lastEdited": 1535583477862827, - "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", - "name": "Particle Rotate", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 3.8216662406921387, - "green": 0.15618896484375, - "red": 1.2409718036651611, - "x": -2.759028196334839, - "y": -9.34381103515625, - "z": -0.17833375930786133 - }, - "queryAACube": { - "scale": 0.3464101552963257, - "x": 1.0677666664123535, - "y": -0.017016112804412842, - "z": 3.648461103439331 - }, - "rotation": { - "w": 0.6747081279754639, - "x": -0.06532388925552368, - "y": -0.6342412233352661, - "z": 0.37175559997558594 - }, - "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", - "scriptTimestamp": 1532724769253, - "shape": "Cube", - "type": "Box", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}", - "visible": false - }, - { - "clientOnly": false, - "color": { - "blue": 0, - "green": 0, - "red": 0 - }, - "created": "2018-08-29T22:57:33Z", - "dimensions": { - "blue": 11.117486953735352, - "green": 3.580313205718994, - "red": 0.20000000298023224, - "x": 0.20000000298023224, - "y": 3.580313205718994, - "z": 11.117486953735352 - }, - "id": "{81a7c620-88ea-4056-b148-449d963c7eb5}", - "lastEdited": 1535583477860260, - "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 0, - "green": 1.1583251953125, - "red": 4.971565246582031, - "x": 0.9715652465820312, - "y": -8.3416748046875, - "z": -4 - }, - "queryAACube": { - "scale": 11.681488037109375, - "x": -0.8691787719726562, - "y": -4.6824188232421875, - "z": -5.8407440185546875 - }, - "rotation": { - "w": 0.8637980222702026, - "x": -4.57763671875e-05, - "y": 0.5038070678710938, - "z": -1.52587890625e-05 - }, - "shape": "Cube", - "type": "Box", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}", - "visible": false - }, - { - "clientOnly": false, - "created": "2018-08-29T22:57:33Z", - "dimensions": { - "blue": 2.1097896099090576, - "green": 0.04847164824604988, - "red": 1.458284616470337, - "x": 1.458284616470337, - "y": 0.04847164824604988, - "z": 2.1097896099090576 - }, - "id": "{09436993-6042-49ff-bfec-0fd28f792251}", - "lastEdited": 1535583477863518, - "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", - "modelURL": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/portal1.fbx", - "name": "Try Again", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 3.946338653564453, - "green": 0.2467041015625, - "red": 1.6013128757476807, - "x": -2.3986871242523193, - "y": -9.2532958984375, - "z": -0.053661346435546875 - }, - "queryAACube": { - "scale": 2.5651814937591553, - "x": 0.318722128868103, - "y": -1.0358866453170776, - "z": 2.663747787475586 - }, - "rotation": { - "w": 0.8220492601394653, - "x": -1.52587890625e-05, - "y": 0.5693598985671997, - "z": -0.0001068115234375 - }, - "script": "file:///C:/Users/wayne/development/tryAgainEntityScript.js", - "shapeType": "static-mesh", - "type": "Model", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}" - }, - { - "angularDamping": 0, - "clientOnly": false, - "color": { - "blue": 0, - "green": 0, - "red": 255 - }, - "created": "2018-08-29T22:57:33Z", - "dimensions": { - "blue": 0.20000000298023224, - "green": 0.20000000298023224, - "red": 0.20000000298023224, - "x": 0.20000000298023224, - "y": 0.20000000298023224, - "z": 0.20000000298023224 - }, - "id": "{86188ae0-6b36-4753-a5c0-0ba31b8ca89a}", - "lastEdited": 1535583477861108, - "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", - "name": "Particle Rotate", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 1.3116319179534912, - "green": 0, - "red": 2.705613613128662, - "x": -1.294386386871338, - "y": -9.5, - "z": -2.688368082046509 - }, - "queryAACube": { - "scale": 0.3464101552963257, - "x": 2.5324084758758545, - "y": -0.17320507764816284, - "z": 1.1384267807006836 - }, - "rotation": { - "w": 0.9127794504165649, - "x": 0.2575265169143677, - "y": 0.15553522109985352, - "z": 0.2761729955673218 - }, - "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", - "scriptTimestamp": 1532724769253, - "shape": "Cube", - "type": "Box", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}", - "visible": false - }, - { - "angularDamping": 0, - "clientOnly": false, - "color": { - "blue": 0, - "green": 0, - "red": 255 - }, - "created": "2018-08-29T22:57:33Z", - "dimensions": { - "blue": 0.20000000298023224, - "green": 0.20000000298023224, - "red": 0.20000000298023224, - "x": 0.20000000298023224, - "y": 0.20000000298023224, - "z": 0.20000000298023224 - }, - "id": "{ffa954a9-43e4-47b1-82c9-b921ed3414b0}", - "lastEdited": 1535583477861316, - "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", - "name": "Particle Rotate", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 3.8216662406921387, - "green": 0.0772705078125, - "red": 1.2409718036651611, - "x": -2.759028196334839, - "y": -9.4227294921875, - "z": -0.17833375930786133 - }, - "queryAACube": { - "scale": 0.3464101552963257, - "x": 1.0677666664123535, - "y": -0.09593456983566284, - "z": 3.648461103439331 - }, - "rotation": { - "w": 0.926024317741394, - "x": 0.20308232307434082, - "y": -0.010269343852996826, - "z": 0.3179827928543091 - }, - "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", - "scriptTimestamp": 1532724769253, - "shape": "Cube", - "type": "Box", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}", - "visible": false - }, - { - "angularDamping": 0, - "clientOnly": false, - "color": { - "blue": 0, - "green": 0, - "red": 255 - }, - "created": "2018-08-29T22:57:33Z", - "dimensions": { - "blue": 0.20000000298023224, - "green": 0.20000000298023224, - "red": 0.20000000298023224, - "x": 0.20000000298023224, - "y": 0.20000000298023224, - "z": 0.20000000298023224 - }, - "id": "{e86df231-a55a-4ca7-ae68-d3271a543d10}", - "lastEdited": 1535583477860886, - "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", - "name": "Particle Rotate", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 3.8216662406921387, - "green": 0, - "red": 1.2409718036651611, - "x": -2.759028196334839, - "y": -9.5, - "z": -0.17833375930786133 - }, - "queryAACube": { - "scale": 0.3464101552963257, - "x": 1.0677666664123535, - "y": -0.17320507764816284, - "z": 3.648461103439331 - }, - "rotation": { - "w": 0.6444342136383057, - "x": -0.08220034837722778, - "y": -0.6649118661880493, - "z": 0.3684900999069214 - }, - "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", - "scriptTimestamp": 1532724769253, - "shape": "Cube", - "type": "Box", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}", - "visible": false - }, - { - "angularDamping": 0, - "clientOnly": false, - "color": { - "blue": 0, - "green": 0, - "red": 255 - }, - "created": "2018-08-29T22:57:33Z", - "dimensions": { - "blue": 0.20000000298023224, - "green": 0.20000000298023224, - "red": 0.20000000298023224, - "x": 0.20000000298023224, - "y": 0.20000000298023224, - "z": 0.20000000298023224 - }, - "id": "{252ffb06-db92-4732-9315-7ee293c24ab8}", - "lastEdited": 1535583477862267, - "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", - "name": "Particle Rotate", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 1.3116319179534912, - "green": 0.15618896484375, - "red": 2.705613613128662, - "x": -1.294386386871338, - "y": -9.34381103515625, - "z": -2.688368082046509 - }, - "queryAACube": { - "scale": 0.3464101552963257, - "x": 2.5324084758758545, - "y": -0.017016112804412842, - "z": 1.1384267807006836 - }, - "rotation": { - "w": 0.46953535079956055, - "x": -0.16719311475753784, - "y": -0.7982757091522217, - "z": 0.3380941152572632 - }, - "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", - "scriptTimestamp": 1532724769253, - "shape": "Cube", - "type": "Box", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}", - "visible": false - }, - { - "clientOnly": false, - "color": { - "blue": 0, - "green": 0, - "red": 0 - }, - "created": "2018-08-29T22:57:33Z", - "dimensions": { - "blue": 11.117486953735352, - "green": 3.580313205718994, - "red": 0.20000000298023224, - "x": 0.20000000298023224, - "y": 3.580313205718994, - "z": 11.117486953735352 - }, - "id": "{1c93807b-311d-48cd-af5e-b477d33b2811}", - "lastEdited": 1535583477860455, - "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 5.268576622009277, - "green": 1.1588134765625, - "red": 6.100250244140625, - "x": 2.100250244140625, - "y": -8.3411865234375, - "z": 1.2685766220092773 - }, - "queryAACube": { - "scale": 11.681488037109375, - "x": 0.2595062255859375, - "y": -4.6819305419921875, - "z": -0.5721673965454102 - }, - "rotation": { - "w": 0.9662165641784668, - "x": -4.57763671875e-05, - "y": -0.2576791048049927, - "z": 1.52587890625e-05 - }, - "shape": "Cube", - "type": "Box", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}", - "visible": false - }, { "alpha": 0, "alphaFinish": 0, @@ -797,7 +889,7 @@ "y": 204, "z": 255 }, - "created": "2018-08-29T22:57:33Z", + "created": "2018-08-31T21:35:56Z", "dimensions": { "blue": 2.5, "green": 2.5, @@ -831,8 +923,8 @@ "emitRate": 2, "emitSpeed": 0, "emitterShouldTrail": true, - "id": "{4cb534d1-5494-4aaa-aa28-ff5cee6e0b8f}", - "lastEdited": 1535583477862081, + "id": "{4e72df75-67d7-4ce2-bdea-e78adae8904a}", + "lastEdited": 1535751362199482, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "lifespan": 10, "maxParticles": 40, @@ -870,144 +962,6 @@ "type": "ParticleEffect", "userData": "{\"grabbableKey\":{\"grabbable\":false}}" }, - { - "clientOnly": false, - "color": { - "blue": 0, - "green": 0, - "red": 0 - }, - "created": "2018-08-29T22:57:33Z", - "dimensions": { - "blue": 11.117486953735352, - "green": 3.580313205718994, - "red": 0.20000000298023224, - "x": 0.20000000298023224, - "y": 3.580313205718994, - "z": 11.117486953735352 - }, - "id": "{a58a8ffe-17ee-4154-b8bb-54e2f0ca9a9d}", - "lastEdited": 1535583477862953, - "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 6.1806135177612305, - "green": 1.1588134765625, - "red": 1.4755167961120605, - "x": -2.5244832038879395, - "y": -8.3411865234375, - "z": 2.1806135177612305 - }, - "queryAACube": { - "scale": 11.681488037109375, - "x": -4.365227222442627, - "y": -4.6819305419921875, - "z": 0.33986949920654297 - }, - "rotation": { - "w": 0.8637980222702026, - "x": -4.57763671875e-05, - "y": 0.5038070678710938, - "z": -1.52587890625e-05 - }, - "shape": "Cube", - "type": "Box", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}", - "visible": false - }, - { - "alpha": 0, - "alphaFinish": 0, - "alphaStart": 0.25, - "clientOnly": false, - "colorFinish": { - "blue": 0, - "green": 0, - "red": 0, - "x": 0, - "y": 0, - "z": 0 - }, - "colorStart": { - "blue": 255, - "green": 255, - "red": 255, - "x": 255, - "y": 255, - "z": 255 - }, - "created": "2018-08-29T22:57:33Z", - "dimensions": { - "blue": 13.24000072479248, - "green": 13.24000072479248, - "red": 13.24000072479248, - "x": 13.24000072479248, - "y": 13.24000072479248, - "z": 13.24000072479248 - }, - "emitAcceleration": { - "blue": 0, - "green": 0.10000000149011612, - "red": 0, - "x": 0, - "y": 0.10000000149011612, - "z": 0 - }, - "emitDimensions": { - "blue": 1, - "green": 1, - "red": 1, - "x": 1, - "y": 1, - "z": 1 - }, - "emitOrientation": { - "w": 1, - "x": -1.52587890625e-05, - "y": -1.52587890625e-05, - "z": -1.52587890625e-05 - }, - "emitRate": 6, - "emitSpeed": 0, - "emitterShouldTrail": true, - "id": "{b6c56e83-f098-422d-a0e8-fd1497c62fbe}", - "lastEdited": 1535583477863251, - "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", - "lifespan": 10, - "maxParticles": 10, - "name": "Stars", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "particleRadius": 0.07000000029802322, - "polarFinish": 3.1415927410125732, - "position": { - "blue": 3.78922963142395, - "green": 0.5220947265625, - "red": 1.1928560733795166, - "x": -2.8071439266204834, - "y": -8.9779052734375, - "z": -0.2107703685760498 - }, - "queryAACube": { - "scale": 22.932353973388672, - "x": -10.273321151733398, - "y": -10.944082260131836, - "z": -7.676947593688965 - }, - "radiusFinish": 0, - "radiusStart": 0, - "rotation": { - "w": 0.996429443359375, - "x": -1.52587890625e-05, - "y": -0.08442819118499756, - "z": -4.57763671875e-05 - }, - "speedSpread": 0, - "spinFinish": null, - "spinStart": null, - "textures": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/star.png", - "type": "ParticleEffect", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}" - }, { "alpha": 0, "alphaFinish": 0, @@ -1034,7 +988,7 @@ "y": 227, "z": 211 }, - "created": "2018-08-29T22:57:33Z", + "created": "2018-08-31T21:35:56Z", "dimensions": { "blue": 2.5, "green": 2.5, @@ -1067,8 +1021,8 @@ }, "emitRate": 2, "emitSpeed": 0, - "id": "{f87fab56-c8d8-4ff8-abf0-35a76dfccf2b}", - "lastEdited": 1535583477862685, + "id": "{3482eecd-0acc-4fb9-bd67-b160fa7c14d7}", + "lastEdited": 1535751362200185, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", "lifespan": 10, "maxParticles": 40, @@ -1108,51 +1062,94 @@ }, { "clientOnly": false, - "created": "2018-08-29T22:57:33Z", + "created": "2018-08-31T21:35:56Z", "dimensions": { - "blue": 2.1097896099090576, - "green": 0.04847164824604988, - "red": 1.458284616470337, - "x": 1.458284616470337, - "y": 0.04847164824604988, - "z": 2.1097896099090576 + "blue": 0.06014331430196762, + "green": 2.582186460494995, + "red": 2.582186698913574, + "x": 2.582186698913574, + "y": 2.582186460494995, + "z": 0.06014331430196762 }, - "id": "{1af53cfc-0cce-467a-96e0-a937f2651ce2}", - "lastEdited": 1535583477863389, + "id": "{729e9f39-5750-42a4-97a8-0fc79b300a32}", + "lastEdited": 1535751362197365, "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", - "modelURL": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/portal2.fbx", - "name": "Back", + "modelURL": "http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/oopsDialog.fbx", + "name": "Oops Dialog", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": { - "blue": 1.5835940837860107, - "green": 0.2467041015625, - "red": 3.0345542430877686, - "x": -0.9654457569122314, - "y": -9.2532958984375, - "z": -2.4164059162139893 + "blue": 1.45927095413208, + "green": 1.6763916015625, + "red": 0, + "x": -4, + "y": -7.8236083984375, + "z": -2.54072904586792 }, "queryAACube": { - "scale": 2.5651814937591553, - "x": 1.751963496208191, - "y": -1.0358866453170776, - "z": 0.3010033369064331 + "scale": 3.6522583961486816, + "x": -1.8261291980743408, + "y": -0.14973759651184082, + "z": -0.36685824394226074 }, "rotation": { - "w": 0.9084458351135254, - "x": -1.52587890625e-05, - "y": 0.4179598093032837, - "z": -0.0001068115234375 + "w": 0.8684672117233276, + "x": -4.57763671875e-05, + "y": 0.4957197904586792, + "z": -7.62939453125e-05 }, - "script": "file:///C:/Users/wayne/development/tryAgainEntityScript.js", - "shapeType": "static-mesh", "type": "Model", "userData": "{\"grabbableKey\":{\"grabbable\":false}}" + }, + { + "angularDamping": 0, + "clientOnly": false, + "color": { + "blue": 0, + "green": 0, + "red": 255 + }, + "created": "2018-08-31T21:35:56Z", + "dimensions": { + "blue": 0.20000000298023224, + "green": 0.20000000298023224, + "red": 0.20000000298023224, + "x": 0.20000000298023224, + "y": 0.20000000298023224, + "z": 0.20000000298023224 + }, + "id": "{bd032130-bbd7-4c0b-9b98-ab9c9362be9b}", + "lastEdited": 1535751362198499, + "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "name": "Particle Rotate", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 3.8216662406921387, + "green": 0.0772705078125, + "red": 1.2409718036651611, + "x": -2.759028196334839, + "y": -9.4227294921875, + "z": -0.17833375930786133 + }, + "queryAACube": { + "scale": 0.3464101552963257, + "x": 1.0677666664123535, + "y": -0.09593456983566284, + "z": 3.648461103439331 + }, + "rotation": { + "w": 0.926024317741394, + "x": 0.20308232307434082, + "y": -0.010269343852996826, + "z": 0.3179827928543091 + }, + "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", + "scriptTimestamp": 1532724769253, + "shape": "Cube", + "type": "Box", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}", + "visible": false } ], - "Paths": - { - "/": "/1.46,-9,0.7/0,0.487,0,0.86663" - }, - "Id": "{351e561a-ee5e-4e8b-87ab-d28677d3b374}", + "Id": "{99bc5288-05fd-4d80-a406-a44c948f7066}", "Version": 93 -} +} \ No newline at end of file diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 86a1421127..e50473bf29 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1185,6 +1185,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo const DomainHandler& domainHandler = nodeList->getDomainHandler(); connect(&domainHandler, SIGNAL(domainURLChanged(QUrl)), SLOT(domainURLChanged(QUrl))); + connect(&domainHandler, SIGNAL(redirectToErrorDomainURL(QUrl)), SLOT(goToErrorDomainURL(QUrl))); connect(&domainHandler, &DomainHandler::domainURLChanged, [](QUrl domainURL){ setCrashAnnotation("domain", domainURL.toString().toStdString()); }); @@ -2251,6 +2252,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo connect(this, &QCoreApplication::aboutToQuit, this, &Application::addAssetToWorldMessageClose); connect(&domainHandler, &DomainHandler::domainURLChanged, this, &Application::addAssetToWorldMessageClose); + connect(&domainHandler, &DomainHandler::redirectToErrorDomainURL, this, &Application::addAssetToWorldMessageClose); updateSystemTabletMode(); @@ -2343,14 +2345,6 @@ void Application::domainConnectionRefused(const QString& reasonMessage, int reas } } -void Application::domainConnectionRedirect() { - auto addressManager = DependencyManager::get(); - - addressManager->handleLookupString(REDIRECT_HIFI_ADDRESS); - getMyAvatar()->setWorldVelocity(glm::vec3(0.0f)); -} - - QString Application::getUserAgent() { if (QThread::currentThread() != thread()) { QString userAgent; @@ -3481,7 +3475,7 @@ void Application::setIsServerlessMode(bool serverlessDomain) { } } -void Application::loadServerlessDomain(QUrl domainURL) { +void Application::loadServerlessDomain(QUrl domainURL, bool errorDomain) { if (QThread::currentThread() != thread()) { QMetaObject::invokeMethod(this, "loadServerlessDomain", Q_ARG(QUrl, domainURL)); return; @@ -3515,8 +3509,11 @@ void Application::loadServerlessDomain(QUrl domainURL) { } std::map namedPaths = tmpTree->getNamedPaths(); - nodeList->getDomainHandler().connectedToServerless(namedPaths); - + if (errorDomain) { + nodeList->getDomainHandler().loadedErrorDomain(namedPaths); + } else { + nodeList->getDomainHandler().connectedToServerless(namedPaths); + } _fullSceneReceivedCounter++; } @@ -6381,6 +6378,7 @@ void Application::clearDomainAvatars() { void Application::domainURLChanged(QUrl domainURL) { // disable physics until we have enough information about our new location to not cause craziness. resetPhysicsReadyInformation(); + auto urlStr = domainURL.toString().toStdString(); setIsServerlessMode(domainURL.scheme() != URL_SCHEME_HIFI); if (isServerlessMode()) { loadServerlessDomain(domainURL); @@ -6388,6 +6386,17 @@ void Application::domainURLChanged(QUrl domainURL) { updateWindowTitle(); } +void Application::goToErrorDomainURL(QUrl errorDomainURL) { + // disable physics until we have enough information about our new location to not cause craziness. + resetPhysicsReadyInformation(); + auto urlStr = errorDomainURL.toString().toStdString(); + setIsServerlessMode(errorDomainURL.scheme() != URL_SCHEME_HIFI); + if (isServerlessMode()) { + loadServerlessDomain(errorDomainURL, true); + } + updateWindowTitle(); +} + void Application::resettingDomain() { _notifiedPacketVersionMismatchThisDomain = false; diff --git a/interface/src/Application.h b/interface/src/Application.h index e38b5a3919..7fe88e9b6a 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -426,7 +426,7 @@ public slots: void setPreferredCursor(const QString& cursor); void setIsServerlessMode(bool serverlessDomain); - void loadServerlessDomain(QUrl domainURL); + void loadServerlessDomain(QUrl domainURL, bool errorDomain = false); void updateVerboseLogging(); @@ -465,6 +465,7 @@ private slots: void setSessionUUID(const QUuid& sessionUUID) const; void domainURLChanged(QUrl domainURL); + void goToErrorDomainURL(QUrl errorDomainURL); void updateWindowTitle() const; void nodeAdded(SharedNodePointer node) const; void nodeActivated(SharedNodePointer node); @@ -474,7 +475,6 @@ private slots: void updateDisplayMode(); void setDisplayPlugin(DisplayPluginPointer newPlugin); void domainConnectionRefused(const QString& reasonMessage, int reason, const QString& extraInfo); - void domainConnectionRedirect(); void addAssetToWorldCheckModelSize(); diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 01db8dfd79..62cd79a609 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -114,6 +114,9 @@ QUrl AddressManager::currentFacingPublicAddress() const { return shareableAddress; } +QUrl AddressManager::lastAddress() const { + return _lastVisitedURL; +} void AddressManager::loadSettings(const QString& lookupString) { #if defined(USE_GLES) && defined(Q_OS_WIN) @@ -151,6 +154,12 @@ void AddressManager::goForward() { } } +void AddressManager::goToLastAddress() { + // this should always return something as long as the URL isn't empty. + auto urlStr = _lastVisitedURL.toString().toStdString(); + handleUrl(_lastVisitedURL, LookupTrigger::AttemptedRefresh); +} + void AddressManager::storeCurrentAddress() { auto url = currentAddress(); @@ -250,9 +259,12 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) { UserActivityLogger::getInstance().wentTo(trigger, URL_TYPE_USER, lookupUrl.toString()); + // save the last visited domain URL. + _lastVisitedURL = lookupUrl; + // in case we're failing to connect to where we thought this user was // store their username as previous lookup so we can refresh their location via API - _previousLookup = lookupUrl; + _previousAPILookup = lookupUrl; } else { // we're assuming this is either a network address or global place name // check if it is a network address first @@ -262,8 +274,11 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) { UserActivityLogger::getInstance().wentTo(trigger, URL_TYPE_NETWORK_ADDRESS, lookupUrl.toString()); + // save the last visited domain URL. + _lastVisitedURL = lookupUrl; + // a network address lookup clears the previous lookup since we don't expect to re-attempt it - _previousLookup.clear(); + _previousAPILookup.clear(); // If the host changed then we have already saved to history if (hostChanged) { @@ -281,8 +296,11 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) { } else if (handleDomainID(lookupUrl.host())){ UserActivityLogger::getInstance().wentTo(trigger, URL_TYPE_DOMAIN_ID, lookupUrl.toString()); + // save the last visited domain URL. + _lastVisitedURL = lookupUrl; + // store this domain ID as the previous lookup in case we're failing to connect and want to refresh API info - _previousLookup = lookupUrl; + _previousAPILookup = lookupUrl; // no place name - this is probably a domain ID // try to look up the domain ID on the metaverse API @@ -290,8 +308,11 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) { } else { UserActivityLogger::getInstance().wentTo(trigger, URL_TYPE_PLACE, lookupUrl.toString()); + // save the last visited domain URL. + _lastVisitedURL = lookupUrl; + // store this place name as the previous lookup in case we fail to connect and want to refresh API info - _previousLookup = lookupUrl; + _previousAPILookup = lookupUrl; // wasn't an address - lookup the place name // we may have a path that defines a relative viewpoint - pass that through the lookup so we can go to it after @@ -305,7 +326,7 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) { qCDebug(networking) << "Going to relative path" << lookupUrl.path(); // a path lookup clears the previous lookup since we don't expect to re-attempt it - _previousLookup.clear(); + _previousAPILookup.clear(); // if this is a relative path then handle it as a relative viewpoint handlePath(lookupUrl.path(), trigger, true); @@ -317,7 +338,10 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) { // be loaded over http(s) // lookupUrl.scheme() == URL_SCHEME_HTTP || // lookupUrl.scheme() == URL_SCHEME_HTTPS || - _previousLookup.clear(); + // TODO once a file can return a connection refusal if there were to be some kind of load error, we'd + // need to store the previous domain tried in _lastVisitedURL. For now , do not store it. + + _previousAPILookup.clear(); _shareablePlaceName.clear(); if (lookupUrl.toString() != REDIRECT_HIFI_ADDRESS) { setDomainInfo(lookupUrl, trigger); @@ -386,7 +410,7 @@ void AddressManager::handleAPIResponse(QNetworkReply* requestReply) { QJsonObject dataObject = responseObject["data"].toObject(); // Lookup succeeded, don't keep re-trying it (especially on server restarts) - _previousLookup.clear(); + _previousAPILookup.clear(); if (!dataObject.isEmpty()) { goToAddressFromObject(dataObject.toVariantMap(), requestReply); @@ -552,7 +576,7 @@ void AddressManager::handleAPIError(QNetworkReply* errorReply) { if (errorReply->error() == QNetworkReply::ContentNotFoundError) { // if this is a lookup that has no result, don't keep re-trying it - _previousLookup.clear(); + _previousAPILookup.clear(); emit lookupResultIsNotFound(); } @@ -847,8 +871,8 @@ void AddressManager::goToUser(const QString& username, bool shouldMatchOrientati void AddressManager::refreshPreviousLookup() { // if we have a non-empty previous lookup, fire it again now (but don't re-store it in the history) - if (!_previousLookup.isEmpty()) { - handleUrl(_previousLookup, LookupTrigger::AttemptedRefresh); + if (!_previousAPILookup.isEmpty()) { + handleUrl(_previousAPILookup, LookupTrigger::AttemptedRefresh); } else { handleUrl(currentAddress(), LookupTrigger::AttemptedRefresh); } diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h index 245517d8cd..fab2bdd6cb 100644 --- a/libraries/networking/src/AddressManager.h +++ b/libraries/networking/src/AddressManager.h @@ -145,6 +145,7 @@ public: UserInput, Back, Forward, + //Retry, StartupFromSettings, DomainPathResponse, Internal, @@ -165,6 +166,8 @@ public: QString currentPath(bool withOrientation = true) const; QString currentFacingPath() const; + QUrl lastAddress() const; + const QUuid& getRootPlaceID() const { return _rootPlaceID; } QString getPlaceName() const; QString getDomainID() const; @@ -246,6 +249,12 @@ public slots: */ void goToUser(const QString& username, bool shouldMatchOrientation = true); + /**jsdoc + * Go to the last address tried. This will be the last URL tried from location.handleLookupString + * @function location.goToLastAddress + */ + void goToLastAddress(); + /**jsdoc * Refresh the current address, e.g., after connecting to a domain in order to position the user to the desired location. * @function location.refreshPreviousLookup @@ -447,6 +456,7 @@ private: void addCurrentAddressToHistory(LookupTrigger trigger); QUrl _domainURL; + QUrl _lastVisitedURL; QUuid _rootPlaceID; PositionGetter _positionGetter; @@ -460,7 +470,7 @@ private: QString _newHostLookupPath; - QUrl _previousLookup; + QUrl _previousAPILookup; }; #endif // hifi_AddressManager_h diff --git a/libraries/networking/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp index 827232129f..0febe1e155 100644 --- a/libraries/networking/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -99,6 +99,7 @@ void DomainHandler::softReset() { clearSettings(); + _isInErrorState = false; _connectionDenialsSinceKeypairRegen = 0; _checkInPacketsSinceLastReply = 0; @@ -129,6 +130,7 @@ void DomainHandler::hardReset() { } void DomainHandler::setErrorDomainURL(const QUrl& url) { + _errorDomainURL = url; return; } @@ -175,7 +177,8 @@ void DomainHandler::setURLAndID(QUrl domainURL, QUuid domainID) { domainPort = DEFAULT_DOMAIN_SERVER_PORT; } - if (_domainURL != domainURL || _sockAddr.getPort() != domainPort) { + // if it's in the error state, reset and try again. + if ((_domainURL != domainURL || _sockAddr.getPort() != domainPort) || _isInErrorState) { // re-set the domain info so that auth information is reloaded hardReset(); @@ -210,7 +213,8 @@ void DomainHandler::setURLAndID(QUrl domainURL, QUuid domainID) { void DomainHandler::setIceServerHostnameAndID(const QString& iceServerHostname, const QUuid& id) { - if (_iceServerSockAddr.getAddress().toString() != iceServerHostname || id != _pendingDomainID) { + // if it's in the error state, reset and try again. + if ((_iceServerSockAddr.getAddress().toString() != iceServerHostname || id != _pendingDomainID) || _isInErrorState) { // re-set the domain info to connect to new domain hardReset(); @@ -320,6 +324,17 @@ void DomainHandler::connectedToServerless(std::map namedPaths) setIsConnected(true); } +void DomainHandler::loadedErrorDomain(std::map namedPaths) { + auto lookup = namedPaths.find("/"); + QString viewpoint; + if (lookup != namedPaths.end()) { + viewpoint = lookup->second; + } else { + viewpoint = DOMAIN_SPAWNING_POINT; + } + DependencyManager::get()->goToViewpointForPath(viewpoint, QString()); +} + void DomainHandler::requestDomainSettings() { qCDebug(networking) << "Requesting settings from domain server"; @@ -461,7 +476,7 @@ void DomainHandler::processDomainServerConnectionDeniedPacket(QSharedPointer namedPaths); + void DomainHandler::loadedErrorDomain(std::map namedPaths); + QString getViewPointFromNamedPath(QString namedPath); bool hasSettings() const { return !_settingsObject.isEmpty(); } @@ -182,7 +184,7 @@ signals: void settingsReceiveFail(); void domainConnectionRefused(QString reasonMessage, int reason, const QString& extraInfo); - void redirectToErrorDomainURL(); + void redirectToErrorDomainURL(QUrl errorDomaunURL); void limitOfSilentDomainCheckInsReached(); From 96aa0549be8d21d05ea5b3826b5d9a869d50c225 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Sat, 1 Sep 2018 12:08:49 -0700 Subject: [PATCH 209/545] AVX2 implementation of crossfade_4x2() --- libraries/audio/src/AudioHRTF.cpp | 6 ++- libraries/audio/src/avx2/AudioHRTF_avx2.cpp | 57 +++++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/libraries/audio/src/AudioHRTF.cpp b/libraries/audio/src/AudioHRTF.cpp index 655527a65c..eea01b703b 100644 --- a/libraries/audio/src/AudioHRTF.cpp +++ b/libraries/audio/src/AudioHRTF.cpp @@ -469,8 +469,12 @@ static void biquad2_4x4(float* src, float* dst, float coef[5][8], float state[3] (*f)(src, dst, coef, state, numFrames); // dispatch } +void crossfade_4x2_AVX2(float* src, float* dst, const float* win, int numFrames); + static void crossfade_4x2(float* src, float* dst, const float* win, int numFrames) { - crossfade_4x2_SSE(src, dst, win, numFrames); + + static auto f = cpuSupportsAVX2() ? crossfade_4x2_AVX2 : crossfade_4x2_SSE; + (*f)(src, dst, win, numFrames); // dispatch } static void interpolate(const float* src0, const float* src1, float* dst, float frac, float gain) { diff --git a/libraries/audio/src/avx2/AudioHRTF_avx2.cpp b/libraries/audio/src/avx2/AudioHRTF_avx2.cpp index 9000df367f..b82098b72f 100644 --- a/libraries/audio/src/avx2/AudioHRTF_avx2.cpp +++ b/libraries/audio/src/avx2/AudioHRTF_avx2.cpp @@ -169,4 +169,61 @@ void biquad2_4x4_AVX2(float* src, float* dst, float coef[5][8], float state[3][8 _mm256_zeroupper(); } +// crossfade 4 inputs into 2 outputs with accumulation (interleaved) +void crossfade_4x2_AVX2(float* src, float* dst, const float* win, int numFrames) { + + assert(numFrames % 8 == 0); + + for (int i = 0; i < numFrames; i += 8) { + + __m256 f0 = _mm256_loadu_ps(&win[i]); + + __m256 x0 = _mm256_castps128_ps256(_mm_loadu_ps(&src[4*i+0])); + __m256 x1 = _mm256_castps128_ps256(_mm_loadu_ps(&src[4*i+4])); + __m256 x2 = _mm256_castps128_ps256(_mm_loadu_ps(&src[4*i+8])); + __m256 x3 = _mm256_castps128_ps256(_mm_loadu_ps(&src[4*i+12])); + + x0 = _mm256_insertf128_ps(x0, _mm_loadu_ps(&src[4*i+16]), 1); + x1 = _mm256_insertf128_ps(x1, _mm_loadu_ps(&src[4*i+20]), 1); + x2 = _mm256_insertf128_ps(x2, _mm_loadu_ps(&src[4*i+24]), 1); + x3 = _mm256_insertf128_ps(x3, _mm_loadu_ps(&src[4*i+28]), 1); + + __m256 y0 = _mm256_loadu_ps(&dst[2*i+0]); + __m256 y1 = _mm256_loadu_ps(&dst[2*i+8]); + + // deinterleave (4x4 matrix transpose) + __m256 t0 = _mm256_unpacklo_ps(x0, x1); + __m256 t1 = _mm256_unpackhi_ps(x0, x1); + __m256 t2 = _mm256_unpacklo_ps(x2, x3); + __m256 t3 = _mm256_unpackhi_ps(x2, x3); + + x0 = _mm256_shuffle_ps(t0, t2, _MM_SHUFFLE(1,0,1,0)); + x1 = _mm256_shuffle_ps(t0, t2, _MM_SHUFFLE(3,2,3,2)); + x2 = _mm256_shuffle_ps(t1, t3, _MM_SHUFFLE(1,0,1,0)); + x3 = _mm256_shuffle_ps(t1, t3, _MM_SHUFFLE(3,2,3,2)); + + // crossfade + x0 = _mm256_sub_ps(x0, x2); + x1 = _mm256_sub_ps(x1, x3); + x2 = _mm256_fmadd_ps(f0, x0, x2); + x3 = _mm256_fmadd_ps(f0, x1, x3); + + // interleave + t0 = _mm256_unpacklo_ps(x2, x3); + t1 = _mm256_unpackhi_ps(x2, x3); + + x0 = _mm256_permute2f128_ps(t0, t1, 0x20); + x1 = _mm256_permute2f128_ps(t0, t1, 0x31); + + // accumulate + y0 = _mm256_add_ps(y0, x0); + y1 = _mm256_add_ps(y1, x1); + + _mm256_storeu_ps(&dst[2*i+0], y0); + _mm256_storeu_ps(&dst[2*i+8], y1); + } + + _mm256_zeroupper(); +} + #endif From e8d922a56cb82adf7d9e0b17c2fe80dcfa4c952d Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 3 Sep 2018 02:48:07 -0700 Subject: [PATCH 210/545] Interleaving the attributes and relying on just 3 input buffers --- libraries/fbx/src/FBXReader_Mesh.cpp | 105 ++++++++++++++++-- .../gpu-gl/src/gpu/gl45/GL45BackendInput.cpp | 11 +- libraries/gpu/src/gpu/Stream.h | 2 + libraries/graphics/src/graphics/Geometry.cpp | 7 ++ libraries/graphics/src/graphics/Geometry.h | 3 + 5 files changed, 116 insertions(+), 12 deletions(-) diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index 801edddb06..13a2c697a0 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -585,13 +585,15 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { FBXMesh& fbxMesh = extractedMesh; graphics::MeshPointer mesh(new graphics::Mesh()); + bool blendShapes = !fbxMesh.blendshapes.empty(); + int numVerts = extractedMesh.vertices.size(); // Grab the vertices in a buffer auto vb = std::make_shared(); vb->setData(extractedMesh.vertices.size() * sizeof(glm::vec3), (const gpu::Byte*) extractedMesh.vertices.data()); gpu::BufferView vbv(vb, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ)); - mesh->setVertexBuffer(vbv); + // mesh->setVertexBuffer(vbv); if (!fbxMesh.normals.empty() && fbxMesh.tangents.empty()) { // Fill with a dummy value to force tangents to be present if there are normals @@ -634,7 +636,10 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { // Normals and tangents are interleaved const int normalsOffset = 0; const int tangentsOffset = normalsOffset + sizeof(NormalType); - const int colorsOffset = normalsOffset + normalsSize + tangentsSize; + const int totalNTSize = normalsOffset + normalsSize + tangentsSize; + //const int colorsOffset = normalsOffset + normalsSize + tangentsSize; + + const int colorsOffset = 0; const int texCoordsOffset = colorsOffset + colorsSize; const int texCoords1Offset = texCoordsOffset + texCoordsSize; const int clusterIndicesOffset = texCoords1Offset + texCoords1Size; @@ -642,6 +647,10 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { const int totalAttributeSize = clusterWeightsOffset + clusterWeightsSize; // Copy all attribute data in a single attribute buffer + + auto attribNTBuffer = std::make_shared(); + attribNTBuffer->resize(totalNTSize); + auto attribBuffer = std::make_shared(); attribBuffer->resize(totalAttributeSize); @@ -665,9 +674,10 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { normalsAndTangents.push_back(packedNormal); normalsAndTangents.push_back(packedTangent); } - attribBuffer->setSubData(normalsOffset, normalsAndTangentsSize, (const gpu::Byte*) normalsAndTangents.data()); + attribNTBuffer->setSubData(normalsOffset, normalsAndTangentsSize, (const gpu::Byte*) normalsAndTangents.data()); } + if (colorsSize > 0) { #if FBX_PACK_COLORS std::vector colors; @@ -723,50 +733,123 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { } attribBuffer->setSubData(clusterWeightsOffset, clusterWeightsSize, (const gpu::Byte*) fbxMesh.clusterWeights.constData()); + auto vf = std::make_shared(); + auto vbs = std::make_shared(); + + gpu::Offset buf0Offset = 12; + vf->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ)); + vbs->addBuffer(vb, 0, buf0Offset); + + gpu::Offset buf1Offset = 0; if (normalsSize) { - mesh->addAttribute(gpu::Stream::NORMAL, + /* mesh->addAttribute(gpu::Stream::NORMAL, graphics::BufferView(attribBuffer, normalsOffset, normalsAndTangentsSize, normalsAndTangentsStride, FBX_NORMAL_ELEMENT)); mesh->addAttribute(gpu::Stream::TANGENT, graphics::BufferView(attribBuffer, tangentsOffset, normalsAndTangentsSize, normalsAndTangentsStride, FBX_NORMAL_ELEMENT)); +*/ + vf->setAttribute(gpu::Stream::NORMAL, 1, FBX_NORMAL_ELEMENT, 0); + vf->setAttribute(gpu::Stream::TANGENT, 1, FBX_NORMAL_ELEMENT, 4); + buf1Offset = 8; + vbs->addBuffer(attribNTBuffer, 0, buf1Offset); } + + gpu::Offset buf2Offset = 0; if (colorsSize) { - mesh->addAttribute(gpu::Stream::COLOR, + /* mesh->addAttribute(gpu::Stream::COLOR, graphics::BufferView(attribBuffer, colorsOffset, colorsSize, FBX_COLOR_ELEMENT)); +*/ + vf->setAttribute(gpu::Stream::COLOR, 2, FBX_COLOR_ELEMENT, buf2Offset); + buf2Offset += 4; } if (texCoordsSize) { - mesh->addAttribute(gpu::Stream::TEXCOORD, + /* mesh->addAttribute(gpu::Stream::TEXCOORD, graphics::BufferView( attribBuffer, texCoordsOffset, texCoordsSize, gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV))); + */ vf->setAttribute(gpu::Stream::TEXCOORD, 2, gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV), buf2Offset); + buf2Offset += 4; } if (texCoords1Size) { - mesh->addAttribute( gpu::Stream::TEXCOORD1, + /* mesh->addAttribute( gpu::Stream::TEXCOORD1, graphics::BufferView(attribBuffer, texCoords1Offset, texCoords1Size, gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV))); + */ vf->setAttribute(gpu::Stream::TEXCOORD1, 2, gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV), buf2Offset); + buf2Offset += 4; } else if (texCoordsSize) { - mesh->addAttribute(gpu::Stream::TEXCOORD1, + /* mesh->addAttribute(gpu::Stream::TEXCOORD1, graphics::BufferView(attribBuffer, texCoordsOffset, texCoordsSize, gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV))); + */ vf->setAttribute(gpu::Stream::TEXCOORD1, 2, gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV), buf2Offset - 4); } if (clusterIndicesSize) { if (fbxMesh.clusters.size() < UINT8_MAX) { - mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, + /* mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, graphics::BufferView(attribBuffer, clusterIndicesOffset, clusterIndicesSize, gpu::Element(gpu::VEC4, gpu::UINT8, gpu::XYZW))); +*/ + vf->setAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, 2, gpu::Element(gpu::VEC4, gpu::UINT8, gpu::XYZW), buf2Offset); + buf2Offset += 4; + } else { - mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, + /* mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, graphics::BufferView(attribBuffer, clusterIndicesOffset, clusterIndicesSize, gpu::Element(gpu::VEC4, gpu::UINT16, gpu::XYZW))); + */ vf->setAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, 2, gpu::Element(gpu::VEC4, gpu::UINT16, gpu::XYZW), buf2Offset); + buf2Offset += 8; } } if (clusterWeightsSize) { - mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, + /* mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, graphics::BufferView(attribBuffer, clusterWeightsOffset, clusterWeightsSize, gpu::Element(gpu::VEC4, gpu::NUINT16, gpu::XYZW))); + */ vf->setAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, 2, gpu::Element(gpu::VEC4, gpu::NUINT16, gpu::XYZW), buf2Offset); + buf2Offset += 8; } + { + auto vColorOffset = 0; + auto vColorSize = colorsSize / numVerts; + + auto vTexcoord0Offset = vColorOffset + vColorSize; + auto vTexcoord0Size = texCoordsSize / numVerts; + + auto vTexcoord1Offset = vTexcoord0Offset + vTexcoord0Size; + auto vTexcoord1Size = texCoords1Size / numVerts; + + auto vClusterIndiceOffset = vTexcoord1Offset + vTexcoord1Size; + auto vClusterIndiceSize = clusterIndicesSize / numVerts; + + auto vClusterWeightOffset = vClusterIndiceOffset + vClusterIndiceSize; + auto vClusterWeightSize = clusterWeightsSize / numVerts; + + auto vStride = vClusterWeightOffset + vClusterWeightSize; + //int vStride = buf2Offset; + std::vector dest; + dest.resize(totalAttributeSize); + auto vDest = dest.data(); + + auto source = attribBuffer->getData(); + + + for (int i = 0; i < numVerts; i++) { + + if (vColorSize) memcpy(vDest + vColorOffset, source + colorsOffset + i * vColorSize, vColorSize); + if (vTexcoord0Size) memcpy(vDest + vTexcoord0Offset, source + texCoordsOffset + i * vTexcoord0Size, vTexcoord0Size); + if (vTexcoord1Size) memcpy(vDest + vTexcoord1Offset, source + texCoords1Offset + i * vTexcoord1Size, vTexcoord1Size); + if (vClusterIndiceSize) memcpy(vDest + vClusterIndiceOffset, source + clusterIndicesOffset + i * vClusterIndiceSize, vClusterIndiceSize); + if (vClusterWeightSize) memcpy(vDest + vClusterWeightOffset, source + clusterWeightsOffset + i * vClusterWeightSize, vClusterWeightSize); + + vDest += vStride; + } + + attribBuffer->setData(totalAttributeSize, dest.data()); + + vbs->addBuffer(attribBuffer, 0, vStride); + } + + mesh->setVertexFormatAndStream(vf, vbs); unsigned int totalIndices = 0; foreach(const FBXMeshPart& part, extractedMesh.parts) { diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp index cc3e609bda..c914b9f84d 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp @@ -27,6 +27,8 @@ void GL45Backend::resetInputStage() { } void GL45Backend::updateInput() { + // PROFILE_RANGE(render_gpu, __FUNCTION__); + bool isStereoNow = isStereo(); // track stereo state change potentially happening wihtout changing the input format // this is a rare case requesting to invalid the format @@ -36,6 +38,7 @@ void GL45Backend::updateInput() { _input._lastUpdateStereoState = isStereoNow; if (_input._invalidFormat) { + PROFILE_RANGE(render_gpu, "bindInputFormat"); InputStageState::ActivationCache newActivation; // Assign the vertex format required @@ -128,16 +131,22 @@ void GL45Backend::updateInput() { } if (_input._invalidBuffers.any()) { + // PROFILE_RANGE(render_gpu, "bindInputBuffers"); auto vbo = _input._bufferVBOs.data(); auto offset = _input._bufferOffsets.data(); auto stride = _input._bufferStrides.data(); - for (GLuint buffer = 0; buffer < _input._buffers.size(); buffer++, vbo++, offset++, stride++) { + int numSet = 0; + auto numBuffers = _input._buffers.size(); + for (GLuint buffer = 0; buffer < numBuffers; buffer++, vbo++, offset++, stride++) { if (_input._invalidBuffers.test(buffer)) { glBindVertexBuffer(buffer, (*vbo), (*offset), (GLsizei)(*stride)); + numSet++; } } + PROFILE_COUNTER_IF_CHANGED(render_gpu, "numVBSbound", int, numSet); + _input._invalidBuffers.reset(); (void)CHECK_GL_ERROR(); } diff --git a/libraries/gpu/src/gpu/Stream.h b/libraries/gpu/src/gpu/Stream.h index 0def1ab201..2e1ed1d83c 100644 --- a/libraries/gpu/src/gpu/Stream.h +++ b/libraries/gpu/src/gpu/Stream.h @@ -152,6 +152,8 @@ public: BufferStream makeRangedStream(uint32 offset, uint32 count = -1) const; + BufferStream& operator = (const BufferStream& src) = default; + protected: Buffers _buffers; Offsets _offsets; diff --git a/libraries/graphics/src/graphics/Geometry.cpp b/libraries/graphics/src/graphics/Geometry.cpp index d43c773249..3f5f484b08 100755 --- a/libraries/graphics/src/graphics/Geometry.cpp +++ b/libraries/graphics/src/graphics/Geometry.cpp @@ -32,6 +32,13 @@ Mesh::Mesh(const Mesh& mesh) : Mesh::~Mesh() { } +void Mesh::setVertexFormatAndStream(const gpu::Stream::FormatPointer& vf, const gpu::BufferStreamPointer& vbs) { + _vertexFormat = vf; + _vertexStream = (*vbs); + + _vertexBuffer = BufferView(vbs->getBuffers()[0], vbs->getOffsets()[0], vbs->getBuffers()[0]->getSize(), vbs->getStrides()[0], gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ)); +} + void Mesh::setVertexBuffer(const BufferView& buffer) { _vertexBuffer = buffer; evalVertexFormat(); diff --git a/libraries/graphics/src/graphics/Geometry.h b/libraries/graphics/src/graphics/Geometry.h index eddfdbd1b6..20018ba71b 100755 --- a/libraries/graphics/src/graphics/Geometry.h +++ b/libraries/graphics/src/graphics/Geometry.h @@ -59,6 +59,9 @@ public: void removeAttribute(Slot slot); const BufferView getAttributeBuffer(int attrib) const; + // Force vertex stream and Vertex format + void setVertexFormatAndStream(const gpu::Stream::FormatPointer& vf, const gpu::BufferStreamPointer& vbs); + // Stream format const gpu::Stream::FormatPointer getVertexFormat() const { return _vertexFormat; } From 06af7b8729595d90ee8dec8dd86d74e7130763a6 Mon Sep 17 00:00:00 2001 From: Flame Soulis Date: Mon, 3 Sep 2018 07:58:39 -0400 Subject: [PATCH 211/545] Fixed typo on DQT_CMAKE_PREFIX_PATH --- BUILD_LINUX.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BUILD_LINUX.md b/BUILD_LINUX.md index 0daef5ae05..55e7260cd1 100644 --- a/BUILD_LINUX.md +++ b/BUILD_LINUX.md @@ -66,7 +66,7 @@ cd hifi/build Prepare makefiles: ```bash -cmake -DQT_CMAKE_PREFIX_PATH=/usr/local/Qt5.10.1/5.10/gcc_64/lib/cmake .. +cmake -DQT_CMAKE_PREFIX_PATH=/usr/local/Qt5.10.1/5.10.1/gcc_64/lib/cmake .. ``` Start compilation and get a cup of coffee: From 229a3bba90e0ed9279e0064067f5353860cfbe2e Mon Sep 17 00:00:00 2001 From: Flame Soulis Date: Mon, 3 Sep 2018 08:00:16 -0400 Subject: [PATCH 212/545] Added zlib1g-dev to required dependencies --- BUILD_LINUX.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILD_LINUX.md b/BUILD_LINUX.md index 55e7260cd1..48e5a8efc1 100644 --- a/BUILD_LINUX.md +++ b/BUILD_LINUX.md @@ -6,7 +6,7 @@ Please read the [general build guide](BUILD.md) for information on dependencies Should you choose not to install Qt5 via a package manager that handles dependencies for you, you may be missing some Qt5 dependencies. On Ubuntu, for example, the following additional packages are required: - libasound2 libxmu-dev libxi-dev freeglut3-dev libasound2-dev libjack0 libjack-dev libxrandr-dev libudev-dev libssl-dev + libasound2 libxmu-dev libxi-dev freeglut3-dev libasound2-dev libjack0 libjack-dev libxrandr-dev libudev-dev libssl-dev zlib1g-dev ## Ubuntu 16.04 specific build guide @@ -20,7 +20,7 @@ sudo dpkg -i hifiqt5.10.1_5.10.1_amd64.deb Install build dependencies: ```bash -sudo apt-get install libasound2 libxmu-dev libxi-dev freeglut3-dev libasound2-dev libjack0 libjack-dev libxrandr-dev libudev-dev libssl-dev +sudo apt-get install libasound2 libxmu-dev libxi-dev freeglut3-dev libasound2-dev libjack0 libjack-dev libxrandr-dev libudev-dev libssl-dev zlib1g-dev ``` To compile interface in a server you must install: From f509dc4af4f9ef5c95640cb7bc680c2071166efb Mon Sep 17 00:00:00 2001 From: Flame Soulis Date: Mon, 3 Sep 2018 08:11:15 -0400 Subject: [PATCH 213/545] Added Ubuntu 18.04 step to add universe repository --- BUILD_LINUX.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/BUILD_LINUX.md b/BUILD_LINUX.md index 48e5a8efc1..421e81c8b8 100644 --- a/BUILD_LINUX.md +++ b/BUILD_LINUX.md @@ -8,7 +8,14 @@ Should you choose not to install Qt5 via a package manager that handles dependen libasound2 libxmu-dev libxi-dev freeglut3-dev libasound2-dev libjack0 libjack-dev libxrandr-dev libudev-dev libssl-dev zlib1g-dev -## Ubuntu 16.04 specific build guide +## Ubuntu 16.04/18.04 specific build guide + +### Ubuntu 18.04 only +Add the universe repository (not enabled by default on the server edition): +```bash +sudo add-apt-repository universe +sudo apt-get update +``` ### Prepare environment hifiqt5.10.1 @@ -33,6 +40,7 @@ Install build tools: sudo apt install cmake ``` + ### Get code and checkout the tag you need Clone this repository: From 03051c0916b48814c92664647b69c2b383e66ab1 Mon Sep 17 00:00:00 2001 From: Flame Soulis Date: Mon, 3 Sep 2018 08:16:50 -0400 Subject: [PATCH 214/545] Revised Qt statement and Improved 18.04 step format --- BUILD_LINUX.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/BUILD_LINUX.md b/BUILD_LINUX.md index 421e81c8b8..c7351d4834 100644 --- a/BUILD_LINUX.md +++ b/BUILD_LINUX.md @@ -11,15 +11,15 @@ Should you choose not to install Qt5 via a package manager that handles dependen ## Ubuntu 16.04/18.04 specific build guide ### Ubuntu 18.04 only -Add the universe repository (not enabled by default on the server edition): +Add the universe repository: +_(This is not enabled by default on the server edition)_ ```bash sudo add-apt-repository universe sudo apt-get update ``` ### Prepare environment -hifiqt5.10.1 -Install qt: +Install Qt 5.10.1: ```bash wget http://debian.highfidelity.com/pool/h/hi/hifiqt5.10.1_5.10.1_amd64.deb sudo dpkg -i hifiqt5.10.1_5.10.1_amd64.deb From b0fe721af19902cccb5a22c533d57f57b497e7fb Mon Sep 17 00:00:00 2001 From: Flame Soulis Date: Mon, 3 Sep 2018 08:22:58 -0400 Subject: [PATCH 215/545] Revised checkout tag and removed download page mention --- BUILD_LINUX.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/BUILD_LINUX.md b/BUILD_LINUX.md index c7351d4834..8b1f77e538 100644 --- a/BUILD_LINUX.md +++ b/BUILD_LINUX.md @@ -56,12 +56,7 @@ git tags Then checkout last tag with: ```bash -git checkout tags/RELEASE-6819 -``` - -Or go to the highfidelity download page (https://highfidelity.com/download) to get the release version. For example, if there is a BETA 6731 type: -```bash -git checkout tags/RELEASE-6731 +git checkout tags/v0.71.0 ``` ### Compiling From 143b4a61dd2821699249ffd8faca60abd88a00a5 Mon Sep 17 00:00:00 2001 From: Flame Soulis Date: Mon, 3 Sep 2018 08:25:45 -0400 Subject: [PATCH 216/545] Revised server compilation statement and grammer error --- BUILD_LINUX.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/BUILD_LINUX.md b/BUILD_LINUX.md index 8b1f77e538..e95ee2f4d4 100644 --- a/BUILD_LINUX.md +++ b/BUILD_LINUX.md @@ -72,12 +72,17 @@ Prepare makefiles: cmake -DQT_CMAKE_PREFIX_PATH=/usr/local/Qt5.10.1/5.10.1/gcc_64/lib/cmake .. ``` -Start compilation and get a cup of coffee: +Start compilation of the server and get a cup of coffee: ```bash -make domain-server assignment-client interface +make domain-server assignment-client ``` -In a server does not make sense to compile interface +To compile interferace: +```bash +make interface +``` + +In a server, it does not make sense to compile interface ### Running the software From 26cb2409b95bafe86e5766b61ca9729bdebcef0d Mon Sep 17 00:00:00 2001 From: Flame Soulis Date: Mon, 3 Sep 2018 08:53:20 -0400 Subject: [PATCH 217/545] Added additional export QT_CMAKE_PREFIX_PATH related to BUILD_LINUX.md --- BUILD.md | 1 + 1 file changed, 1 insertion(+) diff --git a/BUILD.md b/BUILD.md index 4a0274cea6..df3f18cf51 100644 --- a/BUILD.md +++ b/BUILD.md @@ -46,6 +46,7 @@ This can either be entered directly into your shell session before you build or The path it needs to be set to will depend on where and how Qt5 was installed. e.g. + export QT_CMAKE_PREFIX_PATH=/usr/local/Qt5.10.1/5.10.1/gcc_64/lib/cmake export QT_CMAKE_PREFIX_PATH=/usr/local/qt/5.10.1/clang_64/lib/cmake/ export QT_CMAKE_PREFIX_PATH=/usr/local/Cellar/qt5/5.10.1/lib/cmake export QT_CMAKE_PREFIX_PATH=/usr/local/opt/qt5/lib/cmake From 8314386426cf494d6cfe6d0ebd378adc8bde0e84 Mon Sep 17 00:00:00 2001 From: Flame Soulis Date: Mon, 3 Sep 2018 08:55:15 -0400 Subject: [PATCH 218/545] Revised all apt statements to apt-get for consistency --- BUILD_LINUX.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/BUILD_LINUX.md b/BUILD_LINUX.md index e95ee2f4d4..019b19ff8c 100644 --- a/BUILD_LINUX.md +++ b/BUILD_LINUX.md @@ -32,12 +32,12 @@ sudo apt-get install libasound2 libxmu-dev libxi-dev freeglut3-dev libasound2-de To compile interface in a server you must install: ```bash -sudo apt -y install libpulse0 libnss3 libnspr4 libfontconfig1 libxcursor1 libxcomposite1 libxtst6 libxslt1.1 +sudo apt-get -y install libpulse0 libnss3 libnspr4 libfontconfig1 libxcursor1 libxcomposite1 libxtst6 libxslt1.1 ``` Install build tools: ```bash -sudo apt install cmake +sudo apt-get install cmake ``` @@ -101,4 +101,4 @@ Running interface: ./interface/interface ``` -Go to localhost in running interface. +Go to localhost in the running interface. From 94e8ee99f5cade6f6f9a9bcf179c6b229a05cc37 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Mon, 3 Sep 2018 13:06:49 -0700 Subject: [PATCH 219/545] AVX2 implementation of interpolate() --- libraries/audio/src/AudioHRTF.cpp | 6 +++++- libraries/audio/src/avx2/AudioHRTF_avx2.cpp | 22 +++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/libraries/audio/src/AudioHRTF.cpp b/libraries/audio/src/AudioHRTF.cpp index eea01b703b..b52f624620 100644 --- a/libraries/audio/src/AudioHRTF.cpp +++ b/libraries/audio/src/AudioHRTF.cpp @@ -477,8 +477,12 @@ static void crossfade_4x2(float* src, float* dst, const float* win, int numFrame (*f)(src, dst, win, numFrames); // dispatch } +void interpolate_AVX2(const float* src0, const float* src1, float* dst, float frac, float gain); + static void interpolate(const float* src0, const float* src1, float* dst, float frac, float gain) { - interpolate_SSE(src0, src1, dst, frac, gain); + + static auto f = cpuSupportsAVX2() ? interpolate_AVX2 : interpolate_SSE; + (*f)(src0, src1, dst, frac, gain); // dispatch } #else // portable reference code diff --git a/libraries/audio/src/avx2/AudioHRTF_avx2.cpp b/libraries/audio/src/avx2/AudioHRTF_avx2.cpp index b82098b72f..aadbb2d0cd 100644 --- a/libraries/audio/src/avx2/AudioHRTF_avx2.cpp +++ b/libraries/audio/src/avx2/AudioHRTF_avx2.cpp @@ -226,4 +226,26 @@ void crossfade_4x2_AVX2(float* src, float* dst, const float* win, int numFrames) _mm256_zeroupper(); } +// linear interpolation with gain +void interpolate_AVX2(const float* src0, const float* src1, float* dst, float frac, float gain) { + + __m256 f0 = _mm256_set1_ps(gain * (1.0f - frac)); + __m256 f1 = _mm256_set1_ps(gain * frac); + + static_assert(HRTF_TAPS % 8 == 0, "HRTF_TAPS must be a multiple of 8"); + + for (int k = 0; k < HRTF_TAPS; k += 8) { + + __m256 x0 = _mm256_loadu_ps(&src0[k]); + __m256 x1 = _mm256_loadu_ps(&src1[k]); + + x0 = _mm256_mul_ps(f0, x0); + x0 = _mm256_fmadd_ps(f1, x1, x0); + + _mm256_storeu_ps(&dst[k], x0); + } + + _mm256_zeroupper(); +} + #endif From f5b7232f58906e82e24c22b12e778746f946b033 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Mon, 3 Sep 2018 14:00:30 -0700 Subject: [PATCH 220/545] Cleanup --- libraries/audio/src/AudioHRTF.cpp | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/libraries/audio/src/AudioHRTF.cpp b/libraries/audio/src/AudioHRTF.cpp index b52f624620..b639301404 100644 --- a/libraries/audio/src/AudioHRTF.cpp +++ b/libraries/audio/src/AudioHRTF.cpp @@ -446,41 +446,32 @@ static void interpolate_SSE(const float* src0, const float* src1, float* dst, fl void FIR_1x4_AVX2(float* src, float* dst0, float* dst1, float* dst2, float* dst3, float coef[4][HRTF_TAPS], int numFrames); void FIR_1x4_AVX512(float* src, float* dst0, float* dst1, float* dst2, float* dst3, float coef[4][HRTF_TAPS], int numFrames); +void interleave_4x4_AVX2(float* src0, float* src1, float* src2, float* src3, float* dst, int numFrames); +void biquad2_4x4_AVX2(float* src, float* dst, float coef[5][8], float state[3][8], int numFrames); +void crossfade_4x2_AVX2(float* src, float* dst, const float* win, int numFrames); +void interpolate_AVX2(const float* src0, const float* src1, float* dst, float frac, float gain); static void FIR_1x4(float* src, float* dst0, float* dst1, float* dst2, float* dst3, float coef[4][HRTF_TAPS], int numFrames) { - static auto f = cpuSupportsAVX512() ? FIR_1x4_AVX512 : (cpuSupportsAVX2() ? FIR_1x4_AVX2 : FIR_1x4_SSE); (*f)(src, dst0, dst1, dst2, dst3, coef, numFrames); // dispatch } -void interleave_4x4_AVX2(float* src0, float* src1, float* src2, float* src3, float* dst, int numFrames); - static void interleave_4x4(float* src0, float* src1, float* src2, float* src3, float* dst, int numFrames) { - static auto f = cpuSupportsAVX2() ? interleave_4x4_AVX2 : interleave_4x4_SSE; (*f)(src0, src1, src2, src3, dst, numFrames); // dispatch } -void biquad2_4x4_AVX2(float* src, float* dst, float coef[5][8], float state[3][8], int numFrames); - static void biquad2_4x4(float* src, float* dst, float coef[5][8], float state[3][8], int numFrames) { - static auto f = cpuSupportsAVX2() ? biquad2_4x4_AVX2 : biquad2_4x4_SSE; (*f)(src, dst, coef, state, numFrames); // dispatch } -void crossfade_4x2_AVX2(float* src, float* dst, const float* win, int numFrames); - static void crossfade_4x2(float* src, float* dst, const float* win, int numFrames) { - static auto f = cpuSupportsAVX2() ? crossfade_4x2_AVX2 : crossfade_4x2_SSE; (*f)(src, dst, win, numFrames); // dispatch } -void interpolate_AVX2(const float* src0, const float* src1, float* dst, float frac, float gain); - static void interpolate(const float* src0, const float* src1, float* dst, float frac, float gain) { - static auto f = cpuSupportsAVX2() ? interpolate_AVX2 : interpolate_SSE; (*f)(src0, src1, dst, frac, gain); // dispatch } From b5f1c82e61ca6994736dd7f3f04a089f6c241d1b Mon Sep 17 00:00:00 2001 From: Flame Soulis Date: Mon, 3 Sep 2018 18:21:04 -0400 Subject: [PATCH 221/545] Corrected interferace to interface --- BUILD_LINUX.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BUILD_LINUX.md b/BUILD_LINUX.md index 019b19ff8c..1ee3d2b7c8 100644 --- a/BUILD_LINUX.md +++ b/BUILD_LINUX.md @@ -77,7 +77,7 @@ Start compilation of the server and get a cup of coffee: make domain-server assignment-client ``` -To compile interferace: +To compile interface: ```bash make interface ``` From 49e48f5ea0ac96da722b1849332020117e7e3202 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 31 Aug 2018 16:00:27 -0700 Subject: [PATCH 222/545] enable workload regulation by default --- libraries/workload/src/workload/ViewTask.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/workload/src/workload/ViewTask.h b/libraries/workload/src/workload/ViewTask.h index 7c1e4944f5..207bc04276 100644 --- a/libraries/workload/src/workload/ViewTask.h +++ b/libraries/workload/src/workload/ViewTask.h @@ -192,7 +192,7 @@ namespace workload { struct Data { - bool regulateViewRanges{ false }; // regulation is OFF by default + bool regulateViewRanges{ true }; // regulation is ON by default } data; struct DataExport { From c081fd75f7713abce64dbe6e1570428a8e86cf11 Mon Sep 17 00:00:00 2001 From: Liv Erickson Date: Tue, 4 Sep 2018 09:08:35 -0700 Subject: [PATCH 223/545] update serverless content --- cmake/externals/serverless-content/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/externals/serverless-content/CMakeLists.txt b/cmake/externals/serverless-content/CMakeLists.txt index b4cacd8f90..12e2b7a4c6 100644 --- a/cmake/externals/serverless-content/CMakeLists.txt +++ b/cmake/externals/serverless-content/CMakeLists.txt @@ -4,8 +4,8 @@ set(EXTERNAL_NAME serverless-content) ExternalProject_Add( ${EXTERNAL_NAME} - URL http://cdn.highfidelity.com/content-sets/serverless-tutorial-RC72.zip - URL_MD5 b1d8faf9266bfbff88274a484911eb99 + URL http://cdn.highfidelity.com/content-sets/serverless-tutorial-RC73.zip + URL_MD5 0c5edfb63cafb042311d3cf25261fbf2 CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" From 24cf4adb44a55d79fe3a97f1a72dc4c2b238032f Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 4 Sep 2018 09:08:42 -0700 Subject: [PATCH 224/545] Fix MS17902: Prevent case where My Purchases says Open instead of Uninstall --- interface/src/commerce/QmlCommerce.cpp | 59 +++++++++++++++----------- 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/interface/src/commerce/QmlCommerce.cpp b/interface/src/commerce/QmlCommerce.cpp index 1c6600cf3f..06da18148f 100644 --- a/interface/src/commerce/QmlCommerce.cpp +++ b/interface/src/commerce/QmlCommerce.cpp @@ -40,11 +40,9 @@ QmlCommerce::QmlCommerce() { connect(ledger.data(), &Ledger::transferAssetToUsernameResult, this, &QmlCommerce::transferAssetToUsernameResult); connect(ledger.data(), &Ledger::availableUpdatesResult, this, &QmlCommerce::availableUpdatesResult); connect(ledger.data(), &Ledger::updateItemResult, this, &QmlCommerce::updateItemResult); - + auto accountManager = DependencyManager::get(); - connect(accountManager.data(), &AccountManager::usernameChanged, this, [&]() { - setPassphrase(""); - }); + connect(accountManager.data(), &AccountManager::usernameChanged, this, [&]() { setPassphrase(""); }); _appsPath = PathUtils::getAppDataPath() + "Apps/"; } @@ -105,7 +103,11 @@ void QmlCommerce::balance() { } } -void QmlCommerce::inventory(const QString& editionFilter, const QString& typeFilter, const QString& titleFilter, const int& page, const int& perPage) { +void QmlCommerce::inventory(const QString& editionFilter, + const QString& typeFilter, + const QString& titleFilter, + const int& page, + const int& perPage) { auto ledger = DependencyManager::get(); auto wallet = DependencyManager::get(); QStringList cachedPublicKeys = wallet->listPublicKeys(); @@ -166,24 +168,30 @@ void QmlCommerce::certificateInfo(const QString& certificateId) { ledger->certificateInfo(certificateId); } -void QmlCommerce::transferAssetToNode(const QString& nodeID, const QString& certificateID, const int& amount, const QString& optionalMessage) { +void QmlCommerce::transferAssetToNode(const QString& nodeID, + const QString& certificateID, + const int& amount, + const QString& optionalMessage) { auto ledger = DependencyManager::get(); auto wallet = DependencyManager::get(); QStringList keys = wallet->listPublicKeys(); if (keys.count() == 0) { - QJsonObject result{ { "status", "fail" },{ "message", "Uninitialized Wallet." } }; + QJsonObject result{ { "status", "fail" }, { "message", "Uninitialized Wallet." } }; return emit transferAssetToNodeResult(result); } QString key = keys[0]; ledger->transferAssetToNode(key, nodeID, certificateID, amount, optionalMessage); } -void QmlCommerce::transferAssetToUsername(const QString& username, const QString& certificateID, const int& amount, const QString& optionalMessage) { +void QmlCommerce::transferAssetToUsername(const QString& username, + const QString& certificateID, + const int& amount, + const QString& optionalMessage) { auto ledger = DependencyManager::get(); auto wallet = DependencyManager::get(); QStringList keys = wallet->listPublicKeys(); if (keys.count() == 0) { - QJsonObject result{ { "status", "fail" },{ "message", "Uninitialized Wallet." } }; + QJsonObject result{ { "status", "fail" }, { "message", "Uninitialized Wallet." } }; return emit transferAssetToUsernameResult(result); } QString key = keys[0]; @@ -194,10 +202,7 @@ void QmlCommerce::replaceContentSet(const QString& itemHref, const QString& cert auto ledger = DependencyManager::get(); ledger->updateLocation(certificateID, DependencyManager::get()->getPlaceName(), true); qApp->replaceDomainContent(itemHref); - QJsonObject messageProperties = { - { "status", "SuccessfulRequestToReplaceContent" }, - { "content_set_url", itemHref } - }; + QJsonObject messageProperties = { { "status", "SuccessfulRequestToReplaceContent" }, { "content_set_url", itemHref } }; UserActivityLogger::getInstance().logAction("replace_domain_content", messageProperties); emit contentSetChanged(itemHref); @@ -214,10 +219,7 @@ QString QmlCommerce::getInstalledApps(const QString& justInstalledAppID) { QDir directory(_appsPath); QStringList apps = directory.entryList(QStringList("*.app.json")); - foreach(QString appFileName, apps) { - installedAppsFromMarketplace += appFileName; - installedAppsFromMarketplace += ","; - + foreach (QString appFileName, apps) { // If we were supplied a "justInstalledAppID" argument, that means we're entering this function // to get the new list of installed apps immediately after installing an app. // In that case, the app we installed may not yet have its associated script running - @@ -243,10 +245,12 @@ QString QmlCommerce::getInstalledApps(const QString& justInstalledAppID) { // delete the .app.json from the user's local disk. if (!runningScripts.contains(scriptURL)) { if (!appFile.remove()) { - qCWarning(commerce) - << "Couldn't delete local .app.json file (app's script isn't running). App filename is:" - << appFileName; + qCWarning(commerce) << "Couldn't delete local .app.json file (app's script isn't running). App filename is:" + << appFileName; } + } else { + installedAppsFromMarketplace += appFileName; + installedAppsFromMarketplace += ","; } } else { qCDebug(commerce) << "Couldn't open local .app.json file for reading."; @@ -317,7 +321,9 @@ bool QmlCommerce::uninstallApp(const QString& itemHref) { // Read from the file to know what .js script to stop QFile appFile(_appsPath + "/" + appHref.fileName()); if (!appFile.open(QIODevice::ReadOnly)) { - qCDebug(commerce) << "Couldn't open local .app.json file for deletion. Cannot continue with app uninstallation. App filename is:" << appHref.fileName(); + qCDebug(commerce) + << "Couldn't open local .app.json file for deletion. Cannot continue with app uninstallation. App filename is:" + << appHref.fileName(); return false; } QJsonDocument appFileJsonDocument = QJsonDocument::fromJson(appFile.readAll()); @@ -325,13 +331,15 @@ bool QmlCommerce::uninstallApp(const QString& itemHref) { QString scriptUrl = appFileJsonObject["scriptURL"].toString(); if (!DependencyManager::get()->stopScript(scriptUrl.trimmed(), false)) { - qCWarning(commerce) << "Couldn't stop script during app uninstall. Continuing anyway. ScriptURL is:" << scriptUrl.trimmed(); + qCWarning(commerce) << "Couldn't stop script during app uninstall. Continuing anyway. ScriptURL is:" + << scriptUrl.trimmed(); } // Delete the .app.json from the filesystem // remove() closes the file first. if (!appFile.remove()) { - qCWarning(commerce) << "Couldn't delete local .app.json file during app uninstall. Continuing anyway. App filename is:" << appHref.fileName(); + qCWarning(commerce) << "Couldn't delete local .app.json file during app uninstall. Continuing anyway. App filename is:" + << appHref.fileName(); } QFileInfo appFileInfo(appFile); @@ -352,7 +360,8 @@ bool QmlCommerce::openApp(const QString& itemHref) { QJsonObject appFileJsonObject = appFileJsonDocument.object(); QString homeUrl = appFileJsonObject["homeURL"].toString(); - auto tablet = dynamic_cast(DependencyManager::get()->getTablet("com.highfidelity.interface.tablet.system")); + auto tablet = dynamic_cast( + DependencyManager::get()->getTablet("com.highfidelity.interface.tablet.system")); if (homeUrl.contains(".qml", Qt::CaseInsensitive)) { tablet->loadQMLSource(homeUrl); } else if (homeUrl.contains(".html", Qt::CaseInsensitive)) { @@ -377,7 +386,7 @@ void QmlCommerce::updateItem(const QString& certificateId) { auto wallet = DependencyManager::get(); QStringList keys = wallet->listPublicKeys(); if (keys.count() == 0) { - QJsonObject result{ { "status", "fail" },{ "message", "Uninitialized Wallet." } }; + QJsonObject result{ { "status", "fail" }, { "message", "Uninitialized Wallet." } }; return emit updateItemResult(result); } QString key = keys[0]; From 761e8a3f957c2cff43bccd1c8f3e97b6120c5a08 Mon Sep 17 00:00:00 2001 From: sam gateau Date: Tue, 4 Sep 2018 09:19:24 -0700 Subject: [PATCH 225/545] fixing warnings --- libraries/fbx/src/FBXReader_Mesh.cpp | 6 +++--- libraries/graphics/src/graphics/Geometry.cpp | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index 13a2c697a0..e6d9321fb5 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -585,7 +585,7 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { FBXMesh& fbxMesh = extractedMesh; graphics::MeshPointer mesh(new graphics::Mesh()); - bool blendShapes = !fbxMesh.blendshapes.empty(); + // bool blendShapes = !fbxMesh.blendshapes.empty(); int numVerts = extractedMesh.vertices.size(); // Grab the vertices in a buffer @@ -619,7 +619,7 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { qWarning() << "Unexpected tangents in " << url; } const auto normalsAndTangentsSize = normalsSize + tangentsSize; - const int normalsAndTangentsStride = 2 * sizeof(NormalType); + // const int normalsAndTangentsStride = 2 * sizeof(NormalType); const int colorsSize = fbxMesh.colors.size() * sizeof(ColorType); // Texture coordinates are stored in 2 half floats const int texCoordsSize = fbxMesh.texCoords.size() * sizeof(vec2h); @@ -635,7 +635,7 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { // Normals and tangents are interleaved const int normalsOffset = 0; - const int tangentsOffset = normalsOffset + sizeof(NormalType); + // const int tangentsOffset = normalsOffset + sizeof(NormalType); const int totalNTSize = normalsOffset + normalsSize + tangentsSize; //const int colorsOffset = normalsOffset + normalsSize + tangentsSize; diff --git a/libraries/graphics/src/graphics/Geometry.cpp b/libraries/graphics/src/graphics/Geometry.cpp index 3f5f484b08..2fbe3708fd 100755 --- a/libraries/graphics/src/graphics/Geometry.cpp +++ b/libraries/graphics/src/graphics/Geometry.cpp @@ -36,7 +36,9 @@ void Mesh::setVertexFormatAndStream(const gpu::Stream::FormatPointer& vf, const _vertexFormat = vf; _vertexStream = (*vbs); - _vertexBuffer = BufferView(vbs->getBuffers()[0], vbs->getOffsets()[0], vbs->getBuffers()[0]->getSize(), vbs->getStrides()[0], gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ)); + auto attrib = _vertexFormat->getAttribute(gpu::Stream::POSITION); + _vertexBuffer = BufferView(vbs->getBuffers()[attrib._channel], vbs->getOffsets()[attrib._channel], vbs->getBuffers()[attrib._channel]->getSize(), + (gpu::uint16) vbs->getStrides()[attrib._channel], attrib._element); } void Mesh::setVertexBuffer(const BufferView& buffer) { From 3a034fdf66a4311d1e7231cdde608f2fef69d8f2 Mon Sep 17 00:00:00 2001 From: Anthony Thibault Date: Fri, 31 Aug 2018 13:14:15 -0700 Subject: [PATCH 226/545] HMD mode bug fix for avatars with no eyes Previously getCenterEyeCalibrationMat() would return the average eye position for an avatar, if the eyes are missing. Now we fall back to using the HeadCalibrationMat() and adding an offset from the head to the center of the eyes. This is more accurate for characters that don't quite have human proportions. --- interface/src/avatar/MyAvatar.cpp | 4 +++- libraries/shared/src/AvatarConstants.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 640c9821a0..930a1b9f81 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -4313,7 +4313,8 @@ glm::mat4 MyAvatar::getCenterEyeCalibrationMat() const { auto centerEyeRot = Quaternions::Y_180; return createMatFromQuatAndPos(centerEyeRot, centerEyePos / getSensorToWorldScale()); } else { - return createMatFromQuatAndPos(DEFAULT_AVATAR_MIDDLE_EYE_ROT, DEFAULT_AVATAR_MIDDLE_EYE_POS / getSensorToWorldScale()); + glm::mat4 headMat = getHeadCalibrationMat(); + return createMatFromQuatAndPos(DEFAULT_AVATAR_MIDDLE_EYE_ROT, extractTranslation(headMat) + (DEFAULT_AVATAR_HEAD_TO_MIDDLE_EYE_OFFSET / getSensorToWorldScale())); } } @@ -4323,6 +4324,7 @@ glm::mat4 MyAvatar::getHeadCalibrationMat() const { if (headIndex >= 0) { auto headPos = getAbsoluteDefaultJointTranslationInObjectFrame(headIndex); auto headRot = getAbsoluteDefaultJointRotationInObjectFrame(headIndex); + return createMatFromQuatAndPos(headRot, headPos / getSensorToWorldScale()); } else { return createMatFromQuatAndPos(DEFAULT_AVATAR_HEAD_ROT, DEFAULT_AVATAR_HEAD_POS / getSensorToWorldScale()); diff --git a/libraries/shared/src/AvatarConstants.h b/libraries/shared/src/AvatarConstants.h index c3e8a3f173..986d39e94d 100644 --- a/libraries/shared/src/AvatarConstants.h +++ b/libraries/shared/src/AvatarConstants.h @@ -44,7 +44,7 @@ const float DEFAULT_AVATAR_RIGHTHAND_MASS = 2.0f; // Used when avatar is missing joints... (avatar space) const glm::quat DEFAULT_AVATAR_MIDDLE_EYE_ROT { Quaternions::Y_180 }; -const glm::vec3 DEFAULT_AVATAR_MIDDLE_EYE_POS { 0.0f, 0.6f, 0.0f }; +const glm::vec3 DEFAULT_AVATAR_HEAD_TO_MIDDLE_EYE_OFFSET = { 0.0f, 0.06f, -0.09f }; const glm::vec3 DEFAULT_AVATAR_HEAD_POS { 0.0f, 0.53f, 0.0f }; const glm::quat DEFAULT_AVATAR_HEAD_ROT { Quaternions::Y_180 }; const glm::vec3 DEFAULT_AVATAR_RIGHTARM_POS { -0.134824f, 0.396348f, -0.0515777f }; From 058115b79142c4b591c89cf9a9c6f64f0fcf0986 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Tue, 4 Sep 2018 10:38:18 -0700 Subject: [PATCH 227/545] Add guard for sentJointDataOut --- libraries/avatars/src/AvatarData.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index f2f4e2fd7d..3e822fd17a 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -600,7 +600,9 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent } } - (*sentJointDataOut)[i].rotationIsDefaultPose = data.rotationIsDefaultPose; + if (sentJointDataOut) { + (*sentJointDataOut)[i].rotationIsDefaultPose = data.rotationIsDefaultPose; + } if (++validityBit == BITS_IN_BYTE) { *validityPosition++ = validity; @@ -651,7 +653,9 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent } } - (*sentJointDataOut)[i].translationIsDefaultPose = data.translationIsDefaultPose; + if (sentJointDataOut) { + (*sentJointDataOut)[i].translationIsDefaultPose = data.translationIsDefaultPose; + } if (++validityBit == BITS_IN_BYTE) { *validityPosition++ = validity; From fff6a10bcd4ecc7a272ec8ac481fdc6b9a3b3586 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Tue, 4 Sep 2018 10:58:40 -0700 Subject: [PATCH 228/545] Remove some debug logging from safe landing additions --- interface/src/octree/SafeLanding.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/interface/src/octree/SafeLanding.cpp b/interface/src/octree/SafeLanding.cpp index 60b660f66a..cfb0a2c753 100644 --- a/interface/src/octree/SafeLanding.cpp +++ b/interface/src/octree/SafeLanding.cpp @@ -75,7 +75,6 @@ void SafeLanding::addTrackedEntity(const EntityItemID& entityID) { if (hasAABox && downloadedCollisionTypes.count(modelEntity->getShapeType()) != 0) { // Only track entities with downloaded collision bodies. _trackedEntities.emplace(entityID, entity); - qCDebug(interfaceapp) << "Safe Landing: Tracking entity " << entity->getItemName(); } } } @@ -110,7 +109,6 @@ bool SafeLanding::isLoadSequenceComplete() { _initialEnd = INVALID_SEQUENCE; _entityTree = nullptr; EntityTreeRenderer::setEntityLoadingPriorityFunction(StandardPriority); - qCDebug(interfaceapp) << "Safe Landing: load sequence complete"; } return !_trackingEntities; From a7abebd7aac88535d4753def06fc6f88c929a533 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Tue, 4 Sep 2018 11:11:34 -0700 Subject: [PATCH 229/545] adding redirect json to post build in Mac --- interface/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index ded77b9013..cc9fe8ef4c 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -332,6 +332,10 @@ if (APPLE) COMMAND "${CMAKE_COMMAND}" -E copy_directory "${PROJECT_SOURCE_DIR}/resources/fonts" "${RESOURCES_DEV_DIR}/fonts" + # add redirect json to macOS builds. + COMMAND "${CMAKE_COMMAND}" -E copy_if_different + "${PROJECT_SOURCE_DIR}/resources/serverless/redirect.json" + "${RESOURCES_DEV_DIR}/serverless/redirect.json" ) # call the fixup_interface macro to add required bundling commands for installation From ade58a52cc97fe06c2f4bb88c4b9d097636fd4b9 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Tue, 4 Sep 2018 10:33:01 -0700 Subject: [PATCH 230/545] reserve priority sort util vectors --- assignment-client/src/avatars/AvatarMixerSlave.cpp | 1 + interface/src/avatar/AvatarManager.cpp | 5 +++-- libraries/entities-renderer/src/EntityTreeRenderer.cpp | 1 + libraries/shared/src/PrioritySortUtil.h | 3 +++ 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index 59c6db5dc4..c434d82116 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -329,6 +329,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) AvatarData::_avatarSortCoefficientSize, AvatarData::_avatarSortCoefficientCenter, AvatarData::_avatarSortCoefficientAge); + sortedAvatars.reserve(avatarsToSort.size()); // ignore or sort const AvatarSharedPointer& thisAvatar = nodeData->getAvatarSharedPointer(); diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index bd98549510..e9486b9def 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -187,16 +187,17 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { AvatarSharedPointer _avatar; }; + auto avatarMap = getHashCopy(); + AvatarHash::iterator itr = avatarMap.begin(); const auto& views = qApp->getConicalViews(); PrioritySortUtil::PriorityQueue sortedAvatars(views, AvatarData::_avatarSortCoefficientSize, AvatarData::_avatarSortCoefficientCenter, AvatarData::_avatarSortCoefficientAge); + sortedAvatars.reserve(avatarMap.size() - 1); // don't include MyAvatar // sort - auto avatarMap = getHashCopy(); - AvatarHash::iterator itr = avatarMap.begin(); while (itr != avatarMap.end()) { const auto& avatar = std::static_pointer_cast(*itr); // DO NOT update _myAvatar! Its update has already been done earlier in the main loop. diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index a363093083..3d782f69a7 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -382,6 +382,7 @@ void EntityTreeRenderer::updateChangedEntities(const render::ScenePointer& scene const auto& views = _viewState->getConicalViews(); PrioritySortUtil::PriorityQueue sortedRenderables(views); + sortedRenderables.reserve(_renderablesToUpdate.size()); { PROFILE_RANGE_EX(simulation_physics, "SortRenderables", 0xffff00ff, (uint64_t)_renderablesToUpdate.size()); std::unordered_map::iterator itr = _renderablesToUpdate.begin(); diff --git a/libraries/shared/src/PrioritySortUtil.h b/libraries/shared/src/PrioritySortUtil.h index e0137b3d8c..8ded047212 100644 --- a/libraries/shared/src/PrioritySortUtil.h +++ b/libraries/shared/src/PrioritySortUtil.h @@ -100,6 +100,9 @@ namespace PrioritySortUtil { thing.setPriority(computePriority(thing)); _vector.push_back(thing); } + void reserve(size_t num) { + _vector.reserve(num); + } const std::vector& getSortedVector() { std::sort(_vector.begin(), _vector.end(), [](const T& left, const T& right) { return left.getPriority() > right.getPriority(); }); return _vector; From b21fa1037f1ff54fcec00af5026238a8c19a4b20 Mon Sep 17 00:00:00 2001 From: Anthony Thibault Date: Tue, 4 Sep 2018 11:55:52 -0700 Subject: [PATCH 231/545] Code review feedback and bug fixes for calibraiton matrices --- interface/src/avatar/MyAvatar.cpp | 21 +++++++++---------- interface/src/avatar/MyAvatar.h | 2 +- libraries/controllers/src/controllers/Input.h | 20 +++++++++--------- 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 930a1b9f81..e4503b4e78 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -4314,7 +4314,7 @@ glm::mat4 MyAvatar::getCenterEyeCalibrationMat() const { return createMatFromQuatAndPos(centerEyeRot, centerEyePos / getSensorToWorldScale()); } else { glm::mat4 headMat = getHeadCalibrationMat(); - return createMatFromQuatAndPos(DEFAULT_AVATAR_MIDDLE_EYE_ROT, extractTranslation(headMat) + (DEFAULT_AVATAR_HEAD_TO_MIDDLE_EYE_OFFSET / getSensorToWorldScale())); + return createMatFromQuatAndPos(DEFAULT_AVATAR_MIDDLE_EYE_ROT, extractTranslation(headMat) + DEFAULT_AVATAR_HEAD_TO_MIDDLE_EYE_OFFSET); } } @@ -4327,7 +4327,7 @@ glm::mat4 MyAvatar::getHeadCalibrationMat() const { return createMatFromQuatAndPos(headRot, headPos / getSensorToWorldScale()); } else { - return createMatFromQuatAndPos(DEFAULT_AVATAR_HEAD_ROT, DEFAULT_AVATAR_HEAD_POS / getSensorToWorldScale()); + return createMatFromQuatAndPos(DEFAULT_AVATAR_HEAD_ROT, DEFAULT_AVATAR_HEAD_POS); } } @@ -4339,7 +4339,7 @@ glm::mat4 MyAvatar::getSpine2CalibrationMat() const { auto spine2Rot = getAbsoluteDefaultJointRotationInObjectFrame(spine2Index); return createMatFromQuatAndPos(spine2Rot, spine2Pos / getSensorToWorldScale()); } else { - return createMatFromQuatAndPos(DEFAULT_AVATAR_SPINE2_ROT, DEFAULT_AVATAR_SPINE2_POS / getSensorToWorldScale()); + return createMatFromQuatAndPos(DEFAULT_AVATAR_SPINE2_ROT, DEFAULT_AVATAR_SPINE2_POS); } } @@ -4351,7 +4351,7 @@ glm::mat4 MyAvatar::getHipsCalibrationMat() const { auto hipsRot = getAbsoluteDefaultJointRotationInObjectFrame(hipsIndex); return createMatFromQuatAndPos(hipsRot, hipsPos / getSensorToWorldScale()); } else { - return createMatFromQuatAndPos(DEFAULT_AVATAR_HIPS_ROT, DEFAULT_AVATAR_HIPS_POS / getSensorToWorldScale()); + return createMatFromQuatAndPos(DEFAULT_AVATAR_HIPS_ROT, DEFAULT_AVATAR_HIPS_POS); } } @@ -4363,7 +4363,7 @@ glm::mat4 MyAvatar::getLeftFootCalibrationMat() const { auto leftFootRot = getAbsoluteDefaultJointRotationInObjectFrame(leftFootIndex); return createMatFromQuatAndPos(leftFootRot, leftFootPos / getSensorToWorldScale()); } else { - return createMatFromQuatAndPos(DEFAULT_AVATAR_LEFTFOOT_ROT, DEFAULT_AVATAR_LEFTFOOT_POS / getSensorToWorldScale()); + return createMatFromQuatAndPos(DEFAULT_AVATAR_LEFTFOOT_ROT, DEFAULT_AVATAR_LEFTFOOT_POS); } } @@ -4375,11 +4375,10 @@ glm::mat4 MyAvatar::getRightFootCalibrationMat() const { auto rightFootRot = getAbsoluteDefaultJointRotationInObjectFrame(rightFootIndex); return createMatFromQuatAndPos(rightFootRot, rightFootPos / getSensorToWorldScale()); } else { - return createMatFromQuatAndPos(DEFAULT_AVATAR_RIGHTFOOT_ROT, DEFAULT_AVATAR_RIGHTFOOT_POS / getSensorToWorldScale()); + return createMatFromQuatAndPos(DEFAULT_AVATAR_RIGHTFOOT_ROT, DEFAULT_AVATAR_RIGHTFOOT_POS); } } - glm::mat4 MyAvatar::getRightArmCalibrationMat() const { int rightArmIndex = _skeletonModel->getRig().indexOfJoint("RightArm"); if (rightArmIndex >= 0) { @@ -4387,7 +4386,7 @@ glm::mat4 MyAvatar::getRightArmCalibrationMat() const { auto rightArmRot = getAbsoluteDefaultJointRotationInObjectFrame(rightArmIndex); return createMatFromQuatAndPos(rightArmRot, rightArmPos / getSensorToWorldScale()); } else { - return createMatFromQuatAndPos(DEFAULT_AVATAR_RIGHTARM_ROT, DEFAULT_AVATAR_RIGHTARM_POS / getSensorToWorldScale()); + return createMatFromQuatAndPos(DEFAULT_AVATAR_RIGHTARM_ROT, DEFAULT_AVATAR_RIGHTARM_POS); } } @@ -4398,7 +4397,7 @@ glm::mat4 MyAvatar::getLeftArmCalibrationMat() const { auto leftArmRot = getAbsoluteDefaultJointRotationInObjectFrame(leftArmIndex); return createMatFromQuatAndPos(leftArmRot, leftArmPos / getSensorToWorldScale()); } else { - return createMatFromQuatAndPos(DEFAULT_AVATAR_LEFTARM_ROT, DEFAULT_AVATAR_LEFTARM_POS / getSensorToWorldScale()); + return createMatFromQuatAndPos(DEFAULT_AVATAR_LEFTARM_ROT, DEFAULT_AVATAR_LEFTARM_POS); } } @@ -4409,7 +4408,7 @@ glm::mat4 MyAvatar::getRightHandCalibrationMat() const { auto rightHandRot = getAbsoluteDefaultJointRotationInObjectFrame(rightHandIndex); return createMatFromQuatAndPos(rightHandRot, rightHandPos / getSensorToWorldScale()); } else { - return createMatFromQuatAndPos(DEFAULT_AVATAR_RIGHTHAND_ROT, DEFAULT_AVATAR_RIGHTHAND_POS / getSensorToWorldScale()); + return createMatFromQuatAndPos(DEFAULT_AVATAR_RIGHTHAND_ROT, DEFAULT_AVATAR_RIGHTHAND_POS); } } @@ -4420,7 +4419,7 @@ glm::mat4 MyAvatar::getLeftHandCalibrationMat() const { auto leftHandRot = getAbsoluteDefaultJointRotationInObjectFrame(leftHandIndex); return createMatFromQuatAndPos(leftHandRot, leftHandPos / getSensorToWorldScale()); } else { - return createMatFromQuatAndPos(DEFAULT_AVATAR_LEFTHAND_ROT, DEFAULT_AVATAR_LEFTHAND_POS / getSensorToWorldScale()); + return createMatFromQuatAndPos(DEFAULT_AVATAR_LEFTHAND_ROT, DEFAULT_AVATAR_LEFTHAND_POS); } } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 8121b99e55..06267b3819 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -1034,7 +1034,7 @@ public: virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override; virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const override; - // all calibration matrices are in absolute avatar space. + // all calibration matrices are in absolute sensor space. glm::mat4 getCenterEyeCalibrationMat() const; glm::mat4 getHeadCalibrationMat() const; glm::mat4 getSpine2CalibrationMat() const; diff --git a/libraries/controllers/src/controllers/Input.h b/libraries/controllers/src/controllers/Input.h index 3ca4076de2..3c01ee0942 100644 --- a/libraries/controllers/src/controllers/Input.h +++ b/libraries/controllers/src/controllers/Input.h @@ -19,16 +19,16 @@ struct InputCalibrationData { glm::mat4 sensorToWorldMat; // sensor to world glm::mat4 avatarMat; // avatar to world glm::mat4 hmdSensorMat; // hmd pos and orientation in sensor space - glm::mat4 defaultCenterEyeMat; // default pose for the center of the eyes in avatar space. - glm::mat4 defaultHeadMat; // default pose for head joint in avatar space - glm::mat4 defaultSpine2; // default pose for spine2 joint in avatar space - glm::mat4 defaultHips; // default pose for hips joint in avatar space - glm::mat4 defaultLeftFoot; // default pose for leftFoot joint in avatar space - glm::mat4 defaultRightFoot; // default pose for rightFoot joint in avatar space - glm::mat4 defaultRightArm; // default pose for rightArm joint in avatar space - glm::mat4 defaultLeftArm; // default pose for leftArm joint in avatar space - glm::mat4 defaultRightHand; // default pose for rightHand joint in avatar space - glm::mat4 defaultLeftHand; // default pose for leftHand joint in avatar space + glm::mat4 defaultCenterEyeMat; // default pose for the center of the eyes in sensor space. + glm::mat4 defaultHeadMat; // default pose for head joint in sensor space + glm::mat4 defaultSpine2; // default pose for spine2 joint in sensor space + glm::mat4 defaultHips; // default pose for hips joint in sensor space + glm::mat4 defaultLeftFoot; // default pose for leftFoot joint in sensor space + glm::mat4 defaultRightFoot; // default pose for rightFoot joint in sensor space + glm::mat4 defaultRightArm; // default pose for rightArm joint in sensor space + glm::mat4 defaultLeftArm; // default pose for leftArm joint in sensor space + glm::mat4 defaultRightHand; // default pose for rightHand joint in sensor space + glm::mat4 defaultLeftHand; // default pose for leftHand joint in sensor space }; enum class ChannelType { From dff8292216aed7a534b8725fe843ec72af7b88e0 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Tue, 4 Sep 2018 12:50:25 -0700 Subject: [PATCH 232/545] fix framebuffer debug --- .../render-utils/src/DebugDeferredBuffer.cpp | 86 +++++++------------ .../src/debug_deferred_buffer.slf | 12 +-- .../src/render-utils/ShaderConstants.h | 20 +---- 3 files changed, 36 insertions(+), 82 deletions(-) diff --git a/libraries/render-utils/src/DebugDeferredBuffer.cpp b/libraries/render-utils/src/DebugDeferredBuffer.cpp index cab95e50be..0e61b36280 100644 --- a/libraries/render-utils/src/DebugDeferredBuffer.cpp +++ b/libraries/render-utils/src/DebugDeferredBuffer.cpp @@ -38,33 +38,6 @@ void DebugDeferredBufferConfig::setMode(int newMode) { emit dirty(); } -#if 0 -enum TextureSlot { - Albedo = 0, - Normal, - Specular, - Depth, - Lighting, - Shadow, - LinearDepth, - HalfLinearDepth, - HalfNormal, - Curvature, - DiffusedCurvature, - Scattering, - AmbientOcclusion, - AmbientOcclusionBlurred, - Velocity, -}; - -enum ParamSlot { - CameraCorrection = 0, - DeferredFrameTransform, - ShadowTransform, - DebugParametersBuffer -}; -#endif - static const std::string DEFAULT_ALBEDO_SHADER{ "vec4 getFragmentColor() {" " DeferredFragment frag = unpackDeferredFragmentNoPosition(uv);" @@ -178,19 +151,19 @@ static const std::string DEFAULT_SHADOW_CASCADE_SHADER{ static const std::string DEFAULT_LINEAR_DEPTH_SHADER{ "vec4 getFragmentColor() {" - " return vec4(vec3(1.0 - texture(linearDepthMap, uv).x * 0.01), 1.0);" + " return vec4(vec3(1.0 - texture(debugTexture0, uv).x * 0.01), 1.0);" "}" }; static const std::string DEFAULT_HALF_LINEAR_DEPTH_SHADER{ "vec4 getFragmentColor() {" - " return vec4(vec3(1.0 - texture(halfLinearDepthMap, uv).x * 0.01), 1.0);" + " return vec4(vec3(1.0 - texture(debugTexture0, uv).x * 0.01), 1.0);" " }" }; static const std::string DEFAULT_HALF_NORMAL_SHADER{ "vec4 getFragmentColor() {" - " return vec4(vec3(texture(halfNormalMap, uv).xyz), 1.0);" + " return vec4(vec3(texture(debugTexture0, uv).xyz), 1.0);" " }" }; @@ -240,27 +213,27 @@ static const std::string DEFAULT_CURVATURE_OCCLUSION_SHADER{ static const std::string DEFAULT_DEBUG_SCATTERING_SHADER{ "vec4 getFragmentColor() {" - " return vec4(pow(vec3(texture(scatteringMap, uv).xyz), vec3(1.0 / 2.2)), 1.0);" - // " return vec4(vec3(texture(scatteringMap, uv).xyz), 1.0);" + " return vec4(pow(vec3(texture(debugTexture0, uv).xyz), vec3(1.0 / 2.2)), 1.0);" + // " return vec4(vec3(texture(debugTexture0, uv).xyz), 1.0);" " }" }; static const std::string DEFAULT_AMBIENT_OCCLUSION_SHADER{ "vec4 getFragmentColor() {" " return vec4(vec3(texture(obscuranceMap, uv).x), 1.0);" - // When drawing color " return vec4(vec3(texture(occlusionMap, uv).xyz), 1.0);" - // when drawing normal" return vec4(normalize(texture(occlusionMap, uv).xyz * 2.0 - vec3(1.0)), 1.0);" + // When drawing color " return vec4(vec3(texture(debugTexture0, uv).xyz), 1.0);" + // when drawing normal" return vec4(normalize(texture(debugTexture0, uv).xyz * 2.0 - vec3(1.0)), 1.0);" " }" }; static const std::string DEFAULT_AMBIENT_OCCLUSION_BLURRED_SHADER{ "vec4 getFragmentColor() {" - " return vec4(vec3(texture(occlusionBlurredMap, uv).xyz), 1.0);" + " return vec4(vec3(texture(debugTexture0, uv).xyz), 1.0);" " }" }; static const std::string DEFAULT_VELOCITY_SHADER{ "vec4 getFragmentColor() {" - " return vec4(vec2(texture(velocityMap, uv).xy), 0.0, 1.0);" + " return vec4(vec2(texture(debugTexture0, uv).xy), 0.0, 1.0);" " }" }; @@ -463,13 +436,10 @@ void DebugDeferredBuffer::run(const RenderContextPointer& renderContext, const I batch.setResourceTexture(Textures::DeferredDepth, deferredFramebuffer->getPrimaryDepthTexture()); batch.setResourceTexture(Textures::DeferredLighting, deferredFramebuffer->getLightingTexture()); } - if (velocityFramebuffer) { - batch.setResourceTexture(Textures::DebugVelocity, velocityFramebuffer->getVelocityTexture()); + if (velocityFramebuffer && _mode == VelocityMode) { + batch.setResourceTexture(Textures::DebugTexture0, velocityFramebuffer->getVelocityTexture()); } - // FIXME can't find the corresponding buffer - // batch.setUniformBuffer(UBOs:: DebugParametersBuffer, _parameters); - auto lightStage = renderContext->_scene->getStage(); assert(lightStage); assert(lightStage->getNumLights() > 0); @@ -479,12 +449,17 @@ void DebugDeferredBuffer::run(const RenderContextPointer& renderContext, const I batch.setResourceTexture(Textures::Shadow, globalShadow->map); batch.setUniformBuffer(UBOs::ShadowParams, globalShadow->getBuffer()); batch.setUniformBuffer(UBOs::DeferredFrameTransform, frameTransform->getFrameTransformBuffer()); + batch.setUniformBuffer(UBOs::DebugDeferredParams, _parameters); } if (linearDepthTarget) { - batch.setResourceTexture(Textures::DebugDepth, linearDepthTarget->getLinearDepthTexture()); - batch.setResourceTexture(Textures::DebugHalfDepth, linearDepthTarget->getHalfLinearDepthTexture()); - batch.setResourceTexture(Textures::DebugHalfNormal, linearDepthTarget->getHalfNormalTexture()); + if (_mode == DepthMode) { + batch.setResourceTexture(Textures::DebugTexture0, linearDepthTarget->getLinearDepthTexture()); + } else if (_mode == HalfLinearDepthMode) { + batch.setResourceTexture(Textures::DebugTexture0, linearDepthTarget->getHalfLinearDepthTexture()); + } else if (_mode == HalfNormalMode) { + batch.setResourceTexture(Textures::DebugTexture0, linearDepthTarget->getHalfNormalTexture()); + } } if (surfaceGeometryFramebuffer) { batch.setResourceTexture(Textures::DeferredCurvature, surfaceGeometryFramebuffer->getCurvatureTexture()); @@ -492,9 +467,11 @@ void DebugDeferredBuffer::run(const RenderContextPointer& renderContext, const I surfaceGeometryFramebuffer->getLowCurvatureTexture()); } if (ambientOcclusionFramebuffer) { - batch.setResourceTexture(Textures::DebugOcclusion, ambientOcclusionFramebuffer->getOcclusionTexture()); - batch.setResourceTexture(Textures::DebugOcclusionBlurred, - ambientOcclusionFramebuffer->getOcclusionBlurredTexture()); + if (_mode == AmbientOcclusionMode) { + batch.setResourceTexture(Textures::DebugTexture0, ambientOcclusionFramebuffer->getOcclusionTexture()); + } else if (_mode == AmbientOcclusionBlurredMode) { + batch.setResourceTexture(Textures::DebugTexture0, ambientOcclusionFramebuffer->getOcclusionBlurredTexture()); + } } const glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f); const glm::vec2 bottomLeft(_size.x, _size.y); @@ -505,19 +482,14 @@ void DebugDeferredBuffer::run(const RenderContextPointer& renderContext, const I batch.setResourceTexture(Textures::DeferredNormal, nullptr); batch.setResourceTexture(Textures::DeferredSpecular, nullptr); batch.setResourceTexture(Textures::DeferredDepth, nullptr); - batch.setResourceTexture(Textures::DeferredLighting, nullptr); - batch.setResourceTexture(Textures::Shadow, nullptr); - batch.setResourceTexture(Textures::DebugDepth, nullptr); - batch.setResourceTexture(Textures::DebugHalfDepth, nullptr); - batch.setResourceTexture(Textures::DebugHalfNormal, nullptr); - batch.setResourceTexture(Textures::DeferredCurvature, nullptr); batch.setResourceTexture(Textures::DeferredDiffusedCurvature, nullptr); + batch.setResourceTexture(Textures::DeferredLighting, nullptr); - batch.setResourceTexture(Textures::DebugOcclusion, nullptr); - batch.setResourceTexture(Textures::DebugOcclusionBlurred, nullptr); - - batch.setResourceTexture(Textures::DebugVelocity, nullptr); + for (auto i = 0; i < SHADOW_CASCADE_MAX_COUNT; i++) { + batch.setResourceTexture(Textures::Shadow + i, nullptr); + } + batch.setResourceTexture(Textures::DebugTexture0, nullptr); }); } diff --git a/libraries/render-utils/src/debug_deferred_buffer.slf b/libraries/render-utils/src/debug_deferred_buffer.slf index aee04cba90..013640d910 100644 --- a/libraries/render-utils/src/debug_deferred_buffer.slf +++ b/libraries/render-utils/src/debug_deferred_buffer.slf @@ -16,14 +16,8 @@ <@include gpu/Color.slh@> <$declareColorWheel()$> -layout(binding=RENDER_UTILS_TEXTURE_DEBUG_DEPTH) uniform sampler2D linearDepthMap; -layout(binding=RENDER_UTILS_TEXTURE_DEBUG_HALF_DEPTH) uniform sampler2D halfLinearDepthMap; -layout(binding=RENDER_UTILS_TEXTURE_DEBUG_HALF_NORMAL) uniform sampler2D halfNormalMap; -layout(binding=RENDER_UTILS_TEXTURE_DEBUG_OCCLUSION) uniform sampler2D occlusionMap; -layout(binding=RENDER_UTILS_TEXTURE_DEBUG_OCCLUSION_BLURRED) uniform sampler2D occlusionBlurredMap; -layout(binding=RENDER_UTILS_TEXTURE_DEBUG_SCATTERING) uniform sampler2D scatteringMap; -layout(binding=RENDER_UTILS_TEXTURE_DEBUG_VELOCITY) uniform sampler2D velocityMap; -layout(binding=RENDER_UTILS_TEXTURE_DEBUG_SHADOWS) uniform sampler2DArrayShadow shadowMaps; +layout(binding=RENDER_UTILS_DEBUG_TEXTURE0) uniform sampler2D debugTexture0; +layout(binding=RENDER_UTILS_TEXTURE_SHADOW) uniform sampler2DArrayShadow shadowMaps; <@include ShadowCore.slh@> @@ -31,7 +25,7 @@ layout(binding=RENDER_UTILS_TEXTURE_DEBUG_SHADOWS) uniform sampler2DArrayShadow <@include debug_deferred_buffer_shared.slh@> -layout(std140) uniform parametersBuffer { +layout(std140, binding=RENDER_UTILS_BUFFER_DEBUG_DEFERRED_PARAMS) uniform parametersBuffer { DebugParameters parameters; }; diff --git a/libraries/render-utils/src/render-utils/ShaderConstants.h b/libraries/render-utils/src/render-utils/ShaderConstants.h index afb195c240..6a88a62287 100644 --- a/libraries/render-utils/src/render-utils/ShaderConstants.h +++ b/libraries/render-utils/src/render-utils/ShaderConstants.h @@ -126,14 +126,8 @@ // Debugging #define RENDER_UTILS_BUFFER_DEBUG_SKYBOX 5 -#define RENDER_UTILS_TEXTURE_DEBUG_DEPTH 11 -#define RENDER_UTILS_TEXTURE_DEBUG_HALF_DEPTH 12 -#define RENDER_UTILS_TEXTURE_DEBUG_OCCLUSION 13 -#define RENDER_UTILS_TEXTURE_DEBUG_OCCLUSION_BLURRED 14 -#define RENDER_UTILS_TEXTURE_DEBUG_VELOCITY 15 -#define RENDER_UTILS_TEXTURE_DEBUG_SHADOWS 16 -#define RENDER_UTILS_TEXTURE_DEBUG_HALF_NORMAL 17 -#define RENDER_UTILS_TEXTURE_DEBUG_SCATTERING 18 +#define RENDER_UTILS_DEBUG_TEXTURE0 11 +#define RENDER_UTILS_BUFFER_DEBUG_DEFERRED_PARAMS 1 // @@ -174,6 +168,7 @@ enum Buffer { BloomParams = RENDER_UTILS_BUFFER_BLOOM_PARAMS, ToneMappingParams = RENDER_UTILS_BUFFER_TM_PARAMS, ShadowParams = RENDER_UTILS_BUFFER_SHADOW_PARAMS, + DebugDeferredParams = RENDER_UTILS_BUFFER_DEBUG_DEFERRED_PARAMS, }; } // namespace buffer @@ -212,14 +207,7 @@ enum Texture { BloomColor = RENDER_UTILS_TEXTURE_BLOOM_COLOR, ToneMappingColor = RENDER_UTILS_TEXTURE_TM_COLOR, TextFont = RENDER_UTILS_TEXTURE_TEXT_FONT, - DebugDepth = RENDER_UTILS_TEXTURE_DEBUG_DEPTH, - DebugHalfDepth = RENDER_UTILS_TEXTURE_DEBUG_HALF_DEPTH, - DebugOcclusion = RENDER_UTILS_TEXTURE_DEBUG_OCCLUSION, - DebugOcclusionBlurred = RENDER_UTILS_TEXTURE_DEBUG_OCCLUSION_BLURRED, - DebugVelocity = RENDER_UTILS_TEXTURE_DEBUG_VELOCITY, - DebugShadows = RENDER_UTILS_TEXTURE_DEBUG_SHADOWS, - DebugHalfNormal = RENDER_UTILS_TEXTURE_DEBUG_HALF_NORMAL, - DebugScattering = RENDER_UTILS_TEXTURE_DEBUG_SCATTERING, + DebugTexture0 = RENDER_UTILS_DEBUG_TEXTURE0, }; } // namespace texture From ec0b0ab464fcb12b0e01b86cb837470259be2069 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Tue, 4 Sep 2018 12:59:53 -0700 Subject: [PATCH 233/545] fix acceleration spread --- .../src/RenderableParticleEffectEntityItem.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index 18c4921836..1a263fba79 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -187,12 +187,10 @@ ParticleEffectEntityRenderer::CpuParticle ParticleEffectEntityRenderer::createPa particle.basePosition = baseTransform.getTranslation(); // Position, velocity, and acceleration + glm::vec3 emitDirection; if (polarStart == 0.0f && polarFinish == 0.0f && emitDimensions.z == 0.0f) { // Emit along z-axis from position - - particle.velocity = (emitSpeed + randFloatInRange(-1.0f, 1.0f) * speedSpread) * (emitOrientation * Vectors::UNIT_Z); - particle.acceleration = emitAcceleration + randFloatInRange(-1.0f, 1.0f) * accelerationSpread; - + emitDirection = Vectors::UNIT_Z; } else { // Emit around point or from ellipsoid // - Distribute directions evenly around point @@ -210,7 +208,6 @@ ParticleEffectEntityRenderer::CpuParticle ParticleEffectEntityRenderer::createPa azimuth = azimuthStart + (TWO_PI + azimuthFinish - azimuthStart) * randFloat(); } - glm::vec3 emitDirection; if (emitDimensions == Vectors::ZERO) { // Point emitDirection = glm::quat(glm::vec3(PI_OVER_TWO - elevation, 0.0f, azimuth)) * Vectors::UNIT_Z; @@ -235,10 +232,10 @@ ParticleEffectEntityRenderer::CpuParticle ParticleEffectEntityRenderer::createPa )); particle.relativePosition += emitOrientation * emitPosition; } - - particle.velocity = (emitSpeed + randFloatInRange(-1.0f, 1.0f) * speedSpread) * (emitOrientation * emitDirection); - particle.acceleration = emitAcceleration + randFloatInRange(-1.0f, 1.0f) * accelerationSpread; } + particle.velocity = (emitSpeed + randFloatInRange(-1.0f, 1.0f) * speedSpread) * (emitOrientation * emitDirection); + particle.acceleration = emitAcceleration + + glm::vec3(randFloatInRange(-1.0f, 1.0f), randFloatInRange(-1.0f, 1.0f), randFloatInRange(-1.0f, 1.0f)) * accelerationSpread; return particle; } From 22a8164401080f8d55cc3f6ae70eedc2f35a14f6 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Tue, 4 Sep 2018 13:53:03 -0700 Subject: [PATCH 234/545] adding back refusal notifications + domain bounds/floor --- interface/resources/serverless/redirect.json | 1591 +++++++++--------- scripts/system/notifications.js | 2 +- 2 files changed, 833 insertions(+), 760 deletions(-) diff --git a/interface/resources/serverless/redirect.json b/interface/resources/serverless/redirect.json index fd81b6d433..72c4abc16b 100644 --- a/interface/resources/serverless/redirect.json +++ b/interface/resources/serverless/redirect.json @@ -1,37 +1,42 @@ { "DataVersion": 0, + "Paths": + { + "/": "/4,1.4,4/0,0.49544,0,0.868645" + }, "Entities": [ { "clientOnly": false, "collidesWith": "static,dynamic,kinematic,otherAvatar,", "collisionMask": 23, - "created": "2018-08-31T21:40:18Z", + "created": "2018-09-04T20:35:23Z", "dimensions": { - "blue": 0.8231174349784851, - "green": 1.8264780044555664, - "red": 1.2112245559692383, - "x": 1.2112245559692383, - "y": 1.8264780044555664, - "z": 0.8231174349784851 + "blue": 0.8660923838615417, + "green": 1.921838402748108, + "red": 1.2744625806808472, + "x": 1.2744625806808472, + "y": 1.921838402748108, + "z": 0.8660923838615417 }, - "id": "{1a8bf6e0-6f03-4761-9aba-1f624fae1236}", - "lastEdited": 1535751992686833, - "lastEditedBy": "{ace8f357-ad94-49e1-b4d0-39c4d5a936f3}", + "id": "{3889145e-9db2-46dc-9765-9ba7594457dc}", + "lastEdited": 1536093329670067, + "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", + "locked": true, "name": "Try Again Zone", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": { - "blue": 4.442525863647461, + "blue": 4.524896621704102, "green": 1.9289360046386719, - "red": 2.600449562072754, - "x": -1.399550437927246, - "y": -7.571063995361328, - "z": 0.44252586364746094 + "red": 2.893861770629883, + "x": 2.893861770629883, + "y": 1.9289360046386719, + "z": 4.524896621704102 }, "queryAACube": { - "scale": 2.3410699367523193, - "x": 1.4299145936965942, - "y": 0.7584010362625122, - "z": 3.2719907760620117 + "scale": 2.4632973670959473, + "x": 1.6622130870819092, + "y": 0.6972873210906982, + "z": 3.293247938156128 }, "rotation": { "w": 0.9743700623512268, @@ -39,7 +44,7 @@ "y": -0.22495104372501373, "z": 0 }, - "script": "file:///C:/Users/wayne/development/zoneTryAgainEntityScript.js", + "script": "https://raw.githubusercontent.com/wayne-chen/hifi/404DomainRedirect/scripts/redirect/zoneTryAgainEntityScript.js", "shapeType": "box", "type": "Zone", "userData": "{\"grabbableKey\":{\"grabbable\":false}}" @@ -48,33 +53,34 @@ "clientOnly": false, "collidesWith": "static,dynamic,kinematic,otherAvatar,", "collisionMask": 23, - "created": "2018-08-31T21:44:40Z", + "created": "2018-09-04T20:35:23Z", "dimensions": { - "blue": 0.7544999718666077, - "green": 1.8265000581741333, - "red": 1.0555000305175781, - "x": 1.0555000305175781, - "y": 1.8265000581741333, - "z": 0.7544999718666077 + "blue": 1.159199833869934, + "green": 2.8062009811401367, + "red": 1.6216505765914917, + "x": 1.6216505765914917, + "y": 2.8062009811401367, + "z": 1.159199833869934 }, - "id": "{eb439982-948a-4393-8e8c-fdd833e6d9a7}", - "lastEdited": 1535752005525769, - "lastEditedBy": "{ace8f357-ad94-49e1-b4d0-39c4d5a936f3}", + "id": "{8facc8e1-bc17-4460-8a9c-868b07c1b387}", + "lastEdited": 1536093329669913, + "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", + "locked": true, "name": "Back Zone", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": { - "blue": 2.538674831390381, + "blue": 1.8632707595825195, "green": 1.8022732734680176, - "red": 3.5101304054260254, - "x": -0.4898695945739746, - "y": -7.697726726531982, - "z": -1.4613251686096191 + "red": 3.3276727199554443, + "x": 3.3276727199554443, + "y": 1.8022732734680176, + "z": 1.8632707595825195 }, "queryAACube": { - "scale": 2.2404136657714844, - "x": 2.389923572540283, - "y": 0.6820664405822754, - "z": 1.4184679985046387 + "scale": 3.4421300888061523, + "x": 1.6066076755523682, + "y": 0.0812082290649414, + "z": 0.14220571517944336 }, "rotation": { "w": 0.9304176568984985, @@ -82,186 +88,11 @@ "y": -0.36650121212005615, "z": 0 }, - "script": "file:///C:/Users/wayne/development/zoneBackEntityScript.js", + "script": "https://raw.githubusercontent.com/wayne-chen/hifi/404DomainRedirect/scripts/redirect/zoneBackEntityScript.js", "shapeType": "box", "type": "Zone", "userData": "{\"grabbableKey\":{\"grabbable\":false}}" }, - { - "clientOnly": false, - "created": "2018-08-31T21:35:56Z", - "dimensions": { - "blue": 14.40000057220459, - "green": 14.40000057220459, - "red": 14.40000057220459, - "x": 14.40000057220459, - "y": 14.40000057220459, - "z": 14.40000057220459 - }, - "id": "{dbae0b3a-a7ff-4eb1-9177-fd1f20b3cec8}", - "lastEdited": 1535751789461074, - "lastEditedBy": "{ace8f357-ad94-49e1-b4d0-39c4d5a936f3}", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 2.3440732955932617, - "green": 1.7684326171875, - "red": 1.8812973499298096, - "x": -2.1187026500701904, - "y": -7.7315673828125, - "z": -1.6559267044067383 - }, - "queryAACube": { - "scale": 24.9415340423584, - "x": -10.589469909667969, - "y": -10.7023344039917, - "z": -10.126693725585938 - }, - "rotation": { - "w": 0.8697794675827026, - "x": -1.52587890625e-05, - "y": 0.4933699369430542, - "z": -4.57763671875e-05 - }, - "shapeType": "box", - "skyboxMode": "enabled", - "type": "Zone", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}" - }, - { - "clientOnly": false, - "color": { - "blue": 0, - "green": 0, - "red": 0 - }, - "created": "2018-08-31T21:35:56Z", - "dimensions": { - "blue": 11.117486953735352, - "green": 3.580313205718994, - "red": 0.20000000298023224, - "x": 0.20000000298023224, - "y": 3.580313205718994, - "z": 11.117486953735352 - }, - "id": "{c92b026b-e13c-448a-903c-2773f9fdc2e8}", - "lastEdited": 1535751961512543, - "lastEditedBy": "{ace8f357-ad94-49e1-b4d0-39c4d5a936f3}", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 1.9063844680786133, - "green": 1.15850830078125, - "red": 0.16632509231567383, - "x": -3.833674907684326, - "y": -8.34149169921875, - "z": -2.0936155319213867 - }, - "queryAACube": { - "scale": 11.681488037109375, - "x": -5.674418926239014, - "y": -4.6822357177734375, - "z": -3.934359550476074 - }, - "rotation": { - "w": 0.9666743278503418, - "x": -4.57763671875e-05, - "y": -0.2560006380081177, - "z": 1.52587890625e-05 - }, - "shape": "Cube", - "type": "Box", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}", - "visible": false - }, - { - "clientOnly": false, - "color": { - "blue": 0, - "green": 0, - "red": 0 - }, - "created": "2018-08-31T21:35:56Z", - "dimensions": { - "blue": 11.117486953735352, - "green": 3.580313205718994, - "red": 0.20000000298023224, - "x": 0.20000000298023224, - "y": 3.580313205718994, - "z": 11.117486953735352 - }, - "id": "{cd72debb-75a6-420d-b39f-b903fb069798}", - "lastEdited": 1535751362199714, - "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 6.1806135177612305, - "green": 1.1588134765625, - "red": 1.4755167961120605, - "x": -2.5244832038879395, - "y": -8.3411865234375, - "z": 2.1806135177612305 - }, - "queryAACube": { - "scale": 11.681488037109375, - "x": -4.365227222442627, - "y": -4.6819305419921875, - "z": 0.33986949920654297 - }, - "rotation": { - "w": 0.8637980222702026, - "x": -4.57763671875e-05, - "y": 0.5038070678710938, - "z": -1.52587890625e-05 - }, - "shape": "Cube", - "type": "Box", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}", - "visible": false - }, - { - "clientOnly": false, - "color": { - "blue": 0, - "green": 0, - "red": 0 - }, - "created": "2018-08-31T21:35:56Z", - "dimensions": { - "blue": 11.117486953735352, - "green": 3.580313205718994, - "red": 0.20000000298023224, - "x": 0.20000000298023224, - "y": 3.580313205718994, - "z": 11.117486953735352 - }, - "id": "{abe300d5-32b8-4d0c-bf82-e78005b79b70}", - "lastEdited": 1535751362199153, - "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 5.268576622009277, - "green": 1.1588134765625, - "red": 6.100250244140625, - "x": 2.100250244140625, - "y": -8.3411865234375, - "z": 1.2685766220092773 - }, - "queryAACube": { - "scale": 11.681488037109375, - "x": 0.2595062255859375, - "y": -4.6819305419921875, - "z": -0.5721673965454102 - }, - "rotation": { - "w": 0.9662165641784668, - "x": -4.57763671875e-05, - "y": -0.2576791048049927, - "z": 1.52587890625e-05 - }, - "shape": "Cube", - "type": "Box", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}", - "visible": false - }, { "angularDamping": 0, "clientOnly": false, @@ -270,7 +101,7 @@ "green": 0, "red": 255 }, - "created": "2018-08-31T21:35:56Z", + "created": "2018-09-04T20:35:23Z", "dimensions": { "blue": 0.20000000298023224, "green": 0.20000000298023224, @@ -279,18 +110,19 @@ "y": 0.20000000298023224, "z": 0.20000000298023224 }, - "id": "{66757fda-b7ad-4858-83ab-724b01710cc2}", - "lastEdited": 1535751362198937, - "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "id": "{ed4142db-f3c9-441b-9091-cd1755b6aeb1}", + "lastEdited": 1536093329672493, + "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", + "locked": true, "name": "Particle Rotate", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": { "blue": 1.3116319179534912, "green": 0.15618896484375, "red": 2.705613613128662, - "x": -1.294386386871338, - "y": -9.34381103515625, - "z": -2.688368082046509 + "x": 2.705613613128662, + "y": 0.15618896484375, + "z": 1.3116319179534912 }, "queryAACube": { "scale": 0.3464101552963257, @@ -311,148 +143,6 @@ "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false }, - { - "angularDamping": 0, - "clientOnly": false, - "color": { - "blue": 0, - "green": 0, - "red": 255 - }, - "created": "2018-08-31T21:35:56Z", - "dimensions": { - "blue": 0.20000000298023224, - "green": 0.20000000298023224, - "red": 0.20000000298023224, - "x": 0.20000000298023224, - "y": 0.20000000298023224, - "z": 0.20000000298023224 - }, - "id": "{24eda146-92f8-4e43-b084-fb555626427b}", - "lastEdited": 1535751362198263, - "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", - "name": "Particle Rotate", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 1.3116319179534912, - "green": 0, - "red": 2.705613613128662, - "x": -1.294386386871338, - "y": -9.5, - "z": -2.688368082046509 - }, - "queryAACube": { - "scale": 0.3464101552963257, - "x": 2.5324084758758545, - "y": -0.17320507764816284, - "z": 1.1384267807006836 - }, - "rotation": { - "w": 0.9127794504165649, - "x": 0.2575265169143677, - "y": 0.15553522109985352, - "z": 0.2761729955673218 - }, - "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", - "scriptTimestamp": 1532724769253, - "shape": "Cube", - "type": "Box", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}", - "visible": false - }, - { - "alpha": 0, - "alphaFinish": 0, - "alphaStart": 0.25, - "clientOnly": false, - "colorFinish": { - "blue": 0, - "green": 0, - "red": 0, - "x": 0, - "y": 0, - "z": 0 - }, - "colorStart": { - "blue": 255, - "green": 255, - "red": 255, - "x": 255, - "y": 255, - "z": 255 - }, - "created": "2018-08-31T21:35:56Z", - "dimensions": { - "blue": 13.24000072479248, - "green": 13.24000072479248, - "red": 13.24000072479248, - "x": 13.24000072479248, - "y": 13.24000072479248, - "z": 13.24000072479248 - }, - "emitAcceleration": { - "blue": 0, - "green": 0.10000000149011612, - "red": 0, - "x": 0, - "y": 0.10000000149011612, - "z": 0 - }, - "emitDimensions": { - "blue": 1, - "green": 1, - "red": 1, - "x": 1, - "y": 1, - "z": 1 - }, - "emitOrientation": { - "w": 1, - "x": -1.52587890625e-05, - "y": -1.52587890625e-05, - "z": -1.52587890625e-05 - }, - "emitRate": 6, - "emitSpeed": 0, - "emitterShouldTrail": true, - "id": "{b9a46e3e-f982-4a46-b38d-2a38e5cc5fbc}", - "lastEdited": 1535751362199964, - "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", - "lifespan": 10, - "maxParticles": 10, - "name": "Stars", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "particleRadius": 0.07000000029802322, - "polarFinish": 3.1415927410125732, - "position": { - "blue": 3.78922963142395, - "green": 0.5220947265625, - "red": 1.1928560733795166, - "x": -2.8071439266204834, - "y": -8.9779052734375, - "z": -0.2107703685760498 - }, - "queryAACube": { - "scale": 22.932353973388672, - "x": -10.273321151733398, - "y": -10.944082260131836, - "z": -7.676947593688965 - }, - "radiusFinish": 0, - "radiusStart": 0, - "rotation": { - "w": 0.996429443359375, - "x": -1.52587890625e-05, - "y": -0.08442819118499756, - "z": -4.57763671875e-05 - }, - "speedSpread": 0, - "spinFinish": null, - "spinStart": null, - "textures": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/star.png", - "type": "ParticleEffect", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}" - }, { "clientOnly": false, "color": { @@ -460,7 +150,7 @@ "green": 0, "red": 0 }, - "created": "2018-08-31T21:35:56Z", + "created": "2018-09-04T20:35:23Z", "dimensions": { "blue": 11.117486953735352, "green": 3.580313205718994, @@ -469,17 +159,18 @@ "y": 3.580313205718994, "z": 11.117486953735352 }, - "id": "{e6897ca3-1c22-429f-a1b6-173ff47397a7}", - "lastEdited": 1535751362197848, - "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "id": "{d49f29ca-72b6-473d-917c-f7bf7d66f219}", + "lastEdited": 1536093329670344, + "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", + "locked": true, "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": { "blue": 0, "green": 1.1583251953125, "red": 4.971565246582031, - "x": 0.9715652465820312, - "y": -8.3416748046875, - "z": -4 + "x": 4.971565246582031, + "y": 1.1583251953125, + "z": 0 }, "queryAACube": { "scale": 11.681488037109375, @@ -498,6 +189,47 @@ "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false }, + { + "clientOnly": false, + "created": "2018-09-04T20:35:23Z", + "dimensions": { + "blue": 0.06014331430196762, + "green": 2.582186460494995, + "red": 2.582186698913574, + "x": 2.582186698913574, + "y": 2.582186460494995, + "z": 0.06014331430196762 + }, + "id": "{6ccf519b-4e0b-4c23-a51b-305d0a64ab06}", + "lastEdited": 1536093329671943, + "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", + "locked": true, + "modelURL": "http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/oopsDialog.fbx", + "name": "Oops Dialog", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 1.45927095413208, + "green": 1.6763916015625, + "red": 0, + "x": 0, + "y": 1.6763916015625, + "z": 1.45927095413208 + }, + "queryAACube": { + "scale": 3.6522583961486816, + "x": -1.8261291980743408, + "y": -0.14973759651184082, + "z": -0.36685824394226074 + }, + "rotation": { + "w": 0.8684672117233276, + "x": -4.57763671875e-05, + "y": 0.4957197904586792, + "z": -7.62939453125e-05 + }, + "type": "Model", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}" + }, { "angularDamping": 0, "clientOnly": false, @@ -506,7 +238,7 @@ "green": 0, "red": 255 }, - "created": "2018-08-31T21:35:56Z", + "created": "2018-09-04T20:35:23Z", "dimensions": { "blue": 0.20000000298023224, "green": 0.20000000298023224, @@ -515,18 +247,19 @@ "y": 0.20000000298023224, "z": 0.20000000298023224 }, - "id": "{16ca16ab-eee3-41b1-b583-159245aa2010}", - "lastEdited": 1535751362197055, - "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "id": "{625c95a4-1592-4996-bd48-7aa3fdbe6aee}", + "lastEdited": 1536093329671797, + "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", + "locked": true, "name": "Particle Rotate", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": { "blue": 1.3116319179534912, "green": 0.0772705078125, "red": 2.705613613128662, - "x": -1.294386386871338, - "y": -9.4227294921875, - "z": -2.688368082046509 + "x": 2.705613613128662, + "y": 0.0772705078125, + "z": 1.3116319179534912 }, "queryAACube": { "scale": 0.3464101552963257, @@ -549,7 +282,53 @@ }, { "clientOnly": false, - "created": "2018-08-31T21:35:56Z", + "color": { + "blue": 0, + "green": 0, + "red": 255 + }, + "created": "2018-09-04T20:35:23Z", + "dimensions": { + "blue": 8.645400047302246, + "green": 0.20000000298023224, + "red": 20.025121688842773, + "x": 20.025121688842773, + "y": 0.20000000298023224, + "z": 8.645400047302246 + }, + "id": "{d356bb44-7888-476a-821e-961ae7d9330e}", + "lastEdited": 1536093329671479, + "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", + "locked": true, + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 4.846520900726318, + "green": 3.0651936531066895, + "red": 5.746071815490723, + "x": 5.746071815490723, + "y": 3.0651936531066895, + "z": 4.846520900726318 + }, + "queryAACube": { + "scale": 21.812576293945312, + "x": -5.160216331481934, + "y": -7.841094493865967, + "z": -6.059767246246338 + }, + "rotation": { + "w": 0.970295786857605, + "x": 0, + "y": -0.24192190170288086, + "z": 0 + }, + "shape": "Cube", + "type": "Box", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}", + "visible": false + }, + { + "clientOnly": false, + "created": "2018-09-04T20:35:23Z", "dimensions": { "blue": 2.1097896099090576, "green": 0.04847164824604988, @@ -558,9 +337,10 @@ "y": 0.04847164824604988, "z": 2.1097896099090576 }, - "id": "{482ae172-c411-41fb-9a41-4215eef25478}", - "lastEdited": 1535751754378548, - "lastEditedBy": "{ace8f357-ad94-49e1-b4d0-39c4d5a936f3}", + "id": "{737f1b31-0342-4764-89fb-2ef7ddf83983}", + "lastEdited": 1536093329672351, + "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", + "locked": true, "modelURL": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/portal2.fbx", "name": "Back", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", @@ -568,9 +348,9 @@ "blue": 1.5835940837860107, "green": 0.2467041015625, "red": 3.0345542430877686, - "x": -0.9654457569122314, - "y": -9.2532958984375, - "z": -2.4164059162139893 + "x": 3.0345542430877686, + "y": 0.2467041015625, + "z": 1.5835940837860107 }, "queryAACube": { "scale": 2.5651814937591553, @@ -584,97 +364,53 @@ "y": 0.4179598093032837, "z": -0.0001068115234375 }, - "script": "file:///C:/Users/wayne/development/backEntityScript.js", + "script": "https://raw.githubusercontent.com/wayne-chen/hifi/404DomainRedirect/scripts/redirect/backEntityScript.js", "scriptTimestamp": 1535751754379, "shapeType": "static-mesh", "type": "Model", "userData": "{\"grabbableKey\":{\"grabbable\":false}}" }, { - "clientOnly": false, - "created": "2018-08-31T21:35:56Z", - "dimensions": { - "blue": 9.030570983886719, - "green": 0.0719478651881218, - "red": 9.030570983886719, - "x": 9.030570983886719, - "y": 0.0719478651881218, - "z": 9.030570983886719 - }, - "id": "{33440bf8-f9ce-4d52-9b29-1b321e226982}", - "lastEdited": 1535751362197214, - "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", - "modelURL": "http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/floor.fbx", - "name": "Floor", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 4.2324604988098145, - "green": 0.17547607421875, - "red": 4.802988529205322, - "x": 0.8029885292053223, - "y": -9.32452392578125, - "z": 0.23246049880981445 - }, - "queryAACube": { - "scale": 12.771358489990234, - "x": -1.582690715789795, - "y": -6.210203170776367, - "z": -2.1532187461853027 - }, - "rotation": { - "w": 0.8648051023483276, - "x": -1.52587890625e-05, - "y": 0.5020675659179688, - "z": -4.57763671875e-05 - }, - "shapeType": "simple-hull", - "type": "Model", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}" - }, - { - "angularDamping": 0, "clientOnly": false, "color": { "blue": 0, "green": 0, - "red": 255 + "red": 0 }, - "created": "2018-08-31T21:35:56Z", + "created": "2018-09-04T20:35:23Z", "dimensions": { - "blue": 0.20000000298023224, - "green": 0.20000000298023224, + "blue": 11.117486953735352, + "green": 3.580313205718994, "red": 0.20000000298023224, "x": 0.20000000298023224, - "y": 0.20000000298023224, - "z": 0.20000000298023224 + "y": 3.580313205718994, + "z": 11.117486953735352 }, - "id": "{7639140e-cd6f-4f86-97f7-00a19f50253e}", - "lastEdited": 1535751362198721, - "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", - "name": "Particle Rotate", + "id": "{87f734c8-37bb-4ac0-b300-5028f7fe6f9d}", + "lastEdited": 1536093329670472, + "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", + "locked": true, "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": { - "blue": 3.8216662406921387, - "green": 0, - "red": 1.2409718036651611, - "x": -2.759028196334839, - "y": -9.5, - "z": -0.17833375930786133 + "blue": 2.662257671356201, + "green": 1.1585893630981445, + "red": 1.493349552154541, + "x": 1.493349552154541, + "y": 1.1585893630981445, + "z": 2.662257671356201 }, "queryAACube": { - "scale": 0.3464101552963257, - "x": 1.0677666664123535, - "y": -0.17320507764816284, - "z": 3.648461103439331 + "scale": 11.681488037109375, + "x": -4.3473944664001465, + "y": -4.682154655456543, + "z": -3.1784863471984863 }, "rotation": { - "w": 0.6444342136383057, - "x": -0.08220034837722778, - "y": -0.6649118661880493, - "z": 0.3684900999069214 + "w": 0.9666743278503418, + "x": -4.57763671875e-05, + "y": -0.2560006380081177, + "z": 1.52587890625e-05 }, - "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", - "scriptTimestamp": 1532724769253, "shape": "Cube", "type": "Box", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", @@ -682,7 +418,7 @@ }, { "clientOnly": false, - "created": "2018-08-31T21:35:56Z", + "created": "2018-09-04T20:35:23Z", "dimensions": { "blue": 2.1097896099090576, "green": 0.04847164824604988, @@ -691,9 +427,10 @@ "y": 0.04847164824604988, "z": 2.1097896099090576 }, - "id": "{7755bf99-b026-490d-a682-edadd3f65701}", - "lastEdited": 1535751900322535, - "lastEditedBy": "{ace8f357-ad94-49e1-b4d0-39c4d5a936f3}", + "id": "{9584bb57-b543-4d2b-af98-f3de618eef19}", + "lastEdited": 1536093329672070, + "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", + "locked": true, "modelURL": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/portal1.fbx", "name": "Try Again", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", @@ -701,9 +438,9 @@ "blue": 3.946338653564453, "green": 0.2467041015625, "red": 1.6013128757476807, - "x": -2.3986871242523193, - "y": -9.2532958984375, - "z": -0.053661346435546875 + "x": 1.6013128757476807, + "y": 0.2467041015625, + "z": 3.946338653564453 }, "queryAACube": { "scale": 2.5651814937591553, @@ -717,251 +454,11 @@ "y": 0.5693598985671997, "z": -0.0001068115234375 }, - "script": "file:///C:/Users/wayne/development/tryAgainEntityScript.js", + "script": "https://raw.githubusercontent.com/wayne-chen/hifi/404DomainRedirect/scripts/redirect/tryAgainEntityScript.js", "shapeType": "static-mesh", "type": "Model", "userData": "{\"grabbableKey\":{\"grabbable\":false}}" }, - { - "angularDamping": 0, - "clientOnly": false, - "color": { - "blue": 0, - "green": 0, - "red": 255 - }, - "created": "2018-08-31T21:35:56Z", - "dimensions": { - "blue": 0.20000000298023224, - "green": 0.20000000298023224, - "red": 0.20000000298023224, - "x": 0.20000000298023224, - "y": 0.20000000298023224, - "z": 0.20000000298023224 - }, - "id": "{81207b9c-e3f2-4ee1-bb81-0e14f37e4687}", - "lastEdited": 1535751362197613, - "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", - "name": "Particle Rotate", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 3.8216662406921387, - "green": 0.15618896484375, - "red": 1.2409718036651611, - "x": -2.759028196334839, - "y": -9.34381103515625, - "z": -0.17833375930786133 - }, - "queryAACube": { - "scale": 0.3464101552963257, - "x": 1.0677666664123535, - "y": -0.017016112804412842, - "z": 3.648461103439331 - }, - "rotation": { - "w": 0.6747081279754639, - "x": -0.06532388925552368, - "y": -0.6342412233352661, - "z": 0.37175559997558594 - }, - "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", - "scriptTimestamp": 1532724769253, - "shape": "Cube", - "type": "Box", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}", - "visible": false - }, - { - "alpha": 0, - "alphaFinish": 0, - "alphaStart": 0.25, - "clientOnly": false, - "colorFinish": { - "blue": 0, - "green": 0, - "red": 0, - "x": 0, - "y": 0, - "z": 0 - }, - "colorStart": { - "blue": 255, - "green": 255, - "red": 255, - "x": 255, - "y": 255, - "z": 255 - }, - "created": "2018-08-31T21:35:56Z", - "dimensions": { - "blue": 13.24000072479248, - "green": 13.24000072479248, - "red": 13.24000072479248, - "x": 13.24000072479248, - "y": 13.24000072479248, - "z": 13.24000072479248 - }, - "emitAcceleration": { - "blue": 0, - "green": 0.10000000149011612, - "red": 0, - "x": 0, - "y": 0.10000000149011612, - "z": 0 - }, - "emitDimensions": { - "blue": 1, - "green": 1, - "red": 1, - "x": 1, - "y": 1, - "z": 1 - }, - "emitOrientation": { - "w": 1, - "x": -1.52587890625e-05, - "y": -1.52587890625e-05, - "z": -1.52587890625e-05 - }, - "emitRate": 6, - "emitSpeed": 0, - "id": "{b8f11bf5-410e-4e35-b4c3-91c86c01351d}", - "lastEdited": 1535751362196710, - "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", - "lifespan": 10, - "maxParticles": 10, - "name": "Stars", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "particleRadius": 0.07000000029802322, - "polarFinish": 3.1415927410125732, - "position": { - "blue": 1.3712034225463867, - "green": 0.5220947265625, - "red": 2.6281180381774902, - "x": -1.3718819618225098, - "y": -8.9779052734375, - "z": -2.6287965774536133 - }, - "queryAACube": { - "scale": 22.932353973388672, - "x": -8.838058471679688, - "y": -10.944082260131836, - "z": -10.09497356414795 - }, - "radiusFinish": 0, - "radiusStart": 0, - "rotation": { - "w": 0.9852597713470459, - "x": -1.52587890625e-05, - "y": -0.17106890678405762, - "z": -7.62939453125e-05 - }, - "speedSpread": 0, - "spinFinish": null, - "spinStart": null, - "textures": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/star.png", - "type": "ParticleEffect", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}" - }, - { - "alpha": 0, - "alphaFinish": 0, - "alphaStart": 1, - "clientOnly": false, - "color": { - "blue": 255, - "green": 205, - "red": 3 - }, - "colorFinish": { - "blue": 0, - "green": 0, - "red": 0, - "x": 0, - "y": 0, - "z": 0 - }, - "colorStart": { - "blue": 255, - "green": 204, - "red": 0, - "x": 0, - "y": 204, - "z": 255 - }, - "created": "2018-08-31T21:35:56Z", - "dimensions": { - "blue": 2.5, - "green": 2.5, - "red": 2.5, - "x": 2.5, - "y": 2.5, - "z": 2.5 - }, - "emitAcceleration": { - "blue": 0, - "green": 0, - "red": 0, - "x": 0, - "y": 0, - "z": 0 - }, - "emitDimensions": { - "blue": 1, - "green": 1, - "red": 1, - "x": 1, - "y": 1, - "z": 1 - }, - "emitOrientation": { - "w": 0.9993909597396851, - "x": 0.034897372126579285, - "y": -1.525880907138344e-05, - "z": -1.525880907138344e-05 - }, - "emitRate": 2, - "emitSpeed": 0, - "emitterShouldTrail": true, - "id": "{4e72df75-67d7-4ce2-bdea-e78adae8904a}", - "lastEdited": 1535751362199482, - "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", - "lifespan": 10, - "maxParticles": 40, - "name": "Rays", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "particleRadius": 0.75, - "polarFinish": 3.1415927410125732, - "position": { - "blue": 3.814434051513672, - "green": 1.44122314453125, - "red": 1.2319090366363525, - "x": -2.7680909633636475, - "y": -8.05877685546875, - "z": -0.18556594848632812 - }, - "queryAACube": { - "scale": 4.330127239227295, - "x": -0.9331545829772949, - "y": -0.7238404750823975, - "z": 1.6493704319000244 - }, - "radiusFinish": 0.10000000149011612, - "radiusStart": 0, - "rotation": { - "w": 0.9594720602035522, - "x": -1.52587890625e-05, - "y": 0.28178834915161133, - "z": -4.57763671875e-05 - }, - "script": "file:///C:/Users/wayne/development/raysTryAgainEntityScript.js", - "speedSpread": 0, - "spinFinish": null, - "spinStart": null, - "textures": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/stripe.png", - "type": "ParticleEffect", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}" - }, { "alpha": 0, "alphaFinish": 0, @@ -988,7 +485,7 @@ "y": 227, "z": 211 }, - "created": "2018-08-31T21:35:56Z", + "created": "2018-09-04T20:35:23Z", "dimensions": { "blue": 2.5, "green": 2.5, @@ -1021,10 +518,11 @@ }, "emitRate": 2, "emitSpeed": 0, - "id": "{3482eecd-0acc-4fb9-bd67-b160fa7c14d7}", - "lastEdited": 1535751362200185, - "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "id": "{4b942dd2-dcfa-4959-8758-073c56d6a380}", + "lastEdited": 1536093329670643, + "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", "lifespan": 10, + "locked": true, "maxParticles": 40, "name": "Rays", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", @@ -1034,9 +532,9 @@ "blue": 1.3553659915924072, "green": 1.44122314453125, "red": 2.572803497314453, - "x": -1.4271965026855469, - "y": -8.05877685546875, - "z": -2.6446340084075928 + "x": 2.572803497314453, + "y": 1.44122314453125, + "z": 1.3553659915924072 }, "queryAACube": { "scale": 4.330127239227295, @@ -1052,7 +550,6 @@ "y": 0.19707024097442627, "z": -7.62939453125e-05 }, - "script": "file:///C:/Users/wayne/development/raysBackEntityScript.js", "speedSpread": 0, "spinFinish": null, "spinStart": null, @@ -1060,46 +557,6 @@ "type": "ParticleEffect", "userData": "{\"grabbableKey\":{\"grabbable\":false}}" }, - { - "clientOnly": false, - "created": "2018-08-31T21:35:56Z", - "dimensions": { - "blue": 0.06014331430196762, - "green": 2.582186460494995, - "red": 2.582186698913574, - "x": 2.582186698913574, - "y": 2.582186460494995, - "z": 0.06014331430196762 - }, - "id": "{729e9f39-5750-42a4-97a8-0fc79b300a32}", - "lastEdited": 1535751362197365, - "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", - "modelURL": "http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/oopsDialog.fbx", - "name": "Oops Dialog", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 1.45927095413208, - "green": 1.6763916015625, - "red": 0, - "x": -4, - "y": -7.8236083984375, - "z": -2.54072904586792 - }, - "queryAACube": { - "scale": 3.6522583961486816, - "x": -1.8261291980743408, - "y": -0.14973759651184082, - "z": -0.36685824394226074 - }, - "rotation": { - "w": 0.8684672117233276, - "x": -4.57763671875e-05, - "y": 0.4957197904586792, - "z": -7.62939453125e-05 - }, - "type": "Model", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}" - }, { "angularDamping": 0, "clientOnly": false, @@ -1108,7 +565,7 @@ "green": 0, "red": 255 }, - "created": "2018-08-31T21:35:56Z", + "created": "2018-09-04T20:35:23Z", "dimensions": { "blue": 0.20000000298023224, "green": 0.20000000298023224, @@ -1117,18 +574,163 @@ "y": 0.20000000298023224, "z": 0.20000000298023224 }, - "id": "{bd032130-bbd7-4c0b-9b98-ab9c9362be9b}", - "lastEdited": 1535751362198499, - "lastEditedBy": "{8cc0d68c-b354-4c5f-992d-56b89e8072c5}", + "id": "{3b13d766-763a-4d44-99d8-42c7b9d7139e}", + "lastEdited": 1536093329671361, + "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", + "locked": true, + "name": "Particle Rotate", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 3.8216662406921387, + "green": 0, + "red": 1.2409718036651611, + "x": 1.2409718036651611, + "y": 0, + "z": 3.8216662406921387 + }, + "queryAACube": { + "scale": 0.3464101552963257, + "x": 1.0677666664123535, + "y": -0.17320507764816284, + "z": 3.648461103439331 + }, + "rotation": { + "w": 0.6444342136383057, + "x": -0.08220034837722778, + "y": -0.6649118661880493, + "z": 0.3684900999069214 + }, + "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", + "scriptTimestamp": 1532724769253, + "shape": "Cube", + "type": "Box", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}", + "visible": false + }, + { + "alpha": 0, + "alphaFinish": 0, + "alphaStart": 0.25, + "clientOnly": false, + "colorFinish": { + "blue": 0, + "green": 0, + "red": 0, + "x": 0, + "y": 0, + "z": 0 + }, + "colorStart": { + "blue": 255, + "green": 255, + "red": 255, + "x": 255, + "y": 255, + "z": 255 + }, + "created": "2018-09-04T20:35:23Z", + "dimensions": { + "blue": 13.24000072479248, + "green": 13.24000072479248, + "red": 13.24000072479248, + "x": 13.24000072479248, + "y": 13.24000072479248, + "z": 13.24000072479248 + }, + "emitAcceleration": { + "blue": 0, + "green": 0.10000000149011612, + "red": 0, + "x": 0, + "y": 0.10000000149011612, + "z": 0 + }, + "emitDimensions": { + "blue": 1, + "green": 1, + "red": 1, + "x": 1, + "y": 1, + "z": 1 + }, + "emitOrientation": { + "w": 1, + "x": -1.52587890625e-05, + "y": -1.52587890625e-05, + "z": -1.52587890625e-05 + }, + "emitRate": 6, + "emitSpeed": 0, + "emitterShouldTrail": true, + "id": "{e36388d2-7209-4f26-974b-54d314e106a5}", + "lastEdited": 1536093329671654, + "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", + "lifespan": 10, + "locked": true, + "maxParticles": 10, + "name": "Stars", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "particleRadius": 0.07000000029802322, + "polarFinish": 3.1415927410125732, + "position": { + "blue": 3.78922963142395, + "green": 0.5220947265625, + "red": 1.1928560733795166, + "x": 1.1928560733795166, + "y": 0.5220947265625, + "z": 3.78922963142395 + }, + "queryAACube": { + "scale": 22.932353973388672, + "x": -10.273321151733398, + "y": -10.944082260131836, + "z": -7.676947593688965 + }, + "radiusFinish": 0, + "radiusStart": 0, + "rotation": { + "w": 0.996429443359375, + "x": -1.52587890625e-05, + "y": -0.08442819118499756, + "z": -4.57763671875e-05 + }, + "speedSpread": 0, + "spinFinish": null, + "spinStart": null, + "textures": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/star.png", + "type": "ParticleEffect", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}" + }, + { + "angularDamping": 0, + "clientOnly": false, + "color": { + "blue": 0, + "green": 0, + "red": 255 + }, + "created": "2018-09-04T20:35:23Z", + "dimensions": { + "blue": 0.20000000298023224, + "green": 0.20000000298023224, + "red": 0.20000000298023224, + "x": 0.20000000298023224, + "y": 0.20000000298023224, + "z": 0.20000000298023224 + }, + "id": "{1dbde8e2-c715-4c09-814e-e411803278c9}", + "lastEdited": 1536093329670778, + "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", + "locked": true, "name": "Particle Rotate", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": { "blue": 3.8216662406921387, "green": 0.0772705078125, "red": 1.2409718036651611, - "x": -2.759028196334839, - "y": -9.4227294921875, - "z": -0.17833375930786133 + "x": 1.2409718036651611, + "y": 0.0772705078125, + "z": 3.8216662406921387 }, "queryAACube": { "scale": 0.3464101552963257, @@ -1148,8 +750,479 @@ "type": "Box", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false + }, + { + "clientOnly": false, + "color": { + "blue": 0, + "green": 0, + "red": 0 + }, + "created": "2018-09-04T20:35:23Z", + "dimensions": { + "blue": 11.117486953735352, + "green": 3.580313205718994, + "red": 0.20000000298023224, + "x": 0.20000000298023224, + "y": 3.580313205718994, + "z": 11.117486953735352 + }, + "id": "{a06f47da-06e5-4bcd-baa2-37816130f2bd}", + "lastEdited": 1536093329671244, + "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", + "locked": true, + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 6.1806135177612305, + "green": 1.1588134765625, + "red": 1.4755167961120605, + "x": 1.4755167961120605, + "y": 1.1588134765625, + "z": 6.1806135177612305 + }, + "queryAACube": { + "scale": 11.681488037109375, + "x": -4.365227222442627, + "y": -4.6819305419921875, + "z": 0.33986949920654297 + }, + "rotation": { + "w": 0.8637980222702026, + "x": -4.57763671875e-05, + "y": 0.5038070678710938, + "z": -1.52587890625e-05 + }, + "shape": "Cube", + "type": "Box", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}", + "visible": false + }, + { + "alpha": 0, + "alphaFinish": 0, + "alphaStart": 1, + "clientOnly": false, + "color": { + "blue": 255, + "green": 205, + "red": 3 + }, + "colorFinish": { + "blue": 0, + "green": 0, + "red": 0, + "x": 0, + "y": 0, + "z": 0 + }, + "colorStart": { + "blue": 255, + "green": 204, + "red": 0, + "x": 0, + "y": 204, + "z": 255 + }, + "created": "2018-09-04T20:35:23Z", + "dimensions": { + "blue": 2.5, + "green": 2.5, + "red": 2.5, + "x": 2.5, + "y": 2.5, + "z": 2.5 + }, + "emitAcceleration": { + "blue": 0, + "green": 0, + "red": 0, + "x": 0, + "y": 0, + "z": 0 + }, + "emitDimensions": { + "blue": 1, + "green": 1, + "red": 1, + "x": 1, + "y": 1, + "z": 1 + }, + "emitOrientation": { + "w": 0.9993909597396851, + "x": 0.034897372126579285, + "y": -1.525880907138344e-05, + "z": -1.525880907138344e-05 + }, + "emitRate": 2, + "emitSpeed": 0, + "emitterShouldTrail": true, + "id": "{0b1d2de0-39bf-4416-ac72-aae7ddbb3ff0}", + "lastEdited": 1536093329672220, + "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", + "lifespan": 10, + "locked": true, + "maxParticles": 40, + "name": "Rays", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "particleRadius": 0.75, + "polarFinish": 3.1415927410125732, + "position": { + "blue": 3.814434051513672, + "green": 1.44122314453125, + "red": 1.2319090366363525, + "x": 1.2319090366363525, + "y": 1.44122314453125, + "z": 3.814434051513672 + }, + "queryAACube": { + "scale": 4.330127239227295, + "x": -0.9331545829772949, + "y": -0.7238404750823975, + "z": 1.6493704319000244 + }, + "radiusFinish": 0.10000000149011612, + "radiusStart": 0, + "rotation": { + "w": 0.9594720602035522, + "x": -1.52587890625e-05, + "y": 0.28178834915161133, + "z": -4.57763671875e-05 + }, + "speedSpread": 0, + "spinFinish": null, + "spinStart": null, + "textures": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/stripe.png", + "type": "ParticleEffect", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}" + }, + { + "angularDamping": 0, + "clientOnly": false, + "color": { + "blue": 0, + "green": 0, + "red": 255 + }, + "created": "2018-09-04T20:35:23Z", + "dimensions": { + "blue": 0.20000000298023224, + "green": 0.20000000298023224, + "red": 0.20000000298023224, + "x": 0.20000000298023224, + "y": 0.20000000298023224, + "z": 0.20000000298023224 + }, + "id": "{01d9478b-50ae-4f09-b67a-e62a4d133cdf}", + "lastEdited": 1536093329672981, + "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", + "locked": true, + "name": "Particle Rotate", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 3.8216662406921387, + "green": 0.15618896484375, + "red": 1.2409718036651611, + "x": 1.2409718036651611, + "y": 0.15618896484375, + "z": 3.8216662406921387 + }, + "queryAACube": { + "scale": 0.3464101552963257, + "x": 1.0677666664123535, + "y": -0.017016112804412842, + "z": 3.648461103439331 + }, + "rotation": { + "w": 0.6747081279754639, + "x": -0.06532388925552368, + "y": -0.6342412233352661, + "z": 0.37175559997558594 + }, + "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", + "scriptTimestamp": 1532724769253, + "shape": "Cube", + "type": "Box", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}", + "visible": false + }, + { + "clientOnly": false, + "color": { + "blue": 0, + "green": 0, + "red": 0 + }, + "created": "2018-09-04T20:35:23Z", + "dimensions": { + "blue": 6.9401350021362305, + "green": 0.04553089290857315, + "red": 7.004304885864258, + "x": 7.004304885864258, + "y": 0.04553089290857315, + "z": 6.9401350021362305 + }, + "id": "{718b3532-0c3c-4689-ac41-dca8fedffc4a}", + "lastEdited": 1536093496994604, + "lastEditedBy": "{4eecd88f-ef9b-4a83-bb9a-7f7496209c6b}", + "locked": true, + "name": "floor", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 3.6175529956817627, + "green": 0.15221074223518372, + "red": 4.108861923217773, + "x": 4.108861923217773, + "y": 0.15221074223518372, + "z": 3.6175529956817627 + }, + "queryAACube": { + "scale": 9.860417366027832, + "x": -0.8213467597961426, + "y": -4.777997970581055, + "z": -1.3126556873321533 + }, + "rotation": { + "w": 0.8660253882408142, + "x": -1.5922749298624694e-05, + "y": 0.5, + "z": -4.572480611386709e-05 + }, + "shape": "Cube", + "type": "Box", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}" + }, + { + "clientOnly": false, + "color": { + "blue": 0, + "green": 0, + "red": 0 + }, + "created": "2018-09-04T20:35:23Z", + "dimensions": { + "blue": 11.117486953735352, + "green": 3.580313205718994, + "red": 0.20000000298023224, + "x": 0.20000000298023224, + "y": 3.580313205718994, + "z": 11.117486953735352 + }, + "id": "{44442e52-e0cf-45d3-9916-678b8aa56a22}", + "lastEdited": 1536093329672691, + "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", + "locked": true, + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 5.268576622009277, + "green": 1.1588134765625, + "red": 6.100250244140625, + "x": 6.100250244140625, + "y": 1.1588134765625, + "z": 5.268576622009277 + }, + "queryAACube": { + "scale": 11.681488037109375, + "x": 0.2595062255859375, + "y": -4.6819305419921875, + "z": -0.5721673965454102 + }, + "rotation": { + "w": 0.9662165641784668, + "x": -4.57763671875e-05, + "y": -0.2576791048049927, + "z": 1.52587890625e-05 + }, + "shape": "Cube", + "type": "Box", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}", + "visible": false + }, + { + "clientOnly": false, + "created": "2018-09-04T20:35:23Z", + "dimensions": { + "blue": 14.40000057220459, + "green": 14.40000057220459, + "red": 14.40000057220459, + "x": 14.40000057220459, + "y": 14.40000057220459, + "z": 14.40000057220459 + }, + "id": "{8a045310-b82f-4021-9963-0b98d317995c}", + "lastEdited": 1536093329670891, + "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", + "locked": true, + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 2.3440732955932617, + "green": 1.7684326171875, + "red": 1.8812973499298096, + "x": 1.8812973499298096, + "y": 1.7684326171875, + "z": 2.3440732955932617 + }, + "queryAACube": { + "scale": 24.9415340423584, + "x": -10.589469909667969, + "y": -10.7023344039917, + "z": -10.126693725585938 + }, + "rotation": { + "w": 0.8697794675827026, + "x": -1.52587890625e-05, + "y": 0.4933699369430542, + "z": -4.57763671875e-05 + }, + "shapeType": "box", + "skyboxMode": "enabled", + "type": "Zone", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}" + }, + { + "alpha": 0, + "alphaFinish": 0, + "alphaStart": 0.25, + "clientOnly": false, + "colorFinish": { + "blue": 0, + "green": 0, + "red": 0, + "x": 0, + "y": 0, + "z": 0 + }, + "colorStart": { + "blue": 255, + "green": 255, + "red": 255, + "x": 255, + "y": 255, + "z": 255 + }, + "created": "2018-09-04T20:35:23Z", + "dimensions": { + "blue": 13.24000072479248, + "green": 13.24000072479248, + "red": 13.24000072479248, + "x": 13.24000072479248, + "y": 13.24000072479248, + "z": 13.24000072479248 + }, + "emitAcceleration": { + "blue": 0, + "green": 0.10000000149011612, + "red": 0, + "x": 0, + "y": 0.10000000149011612, + "z": 0 + }, + "emitDimensions": { + "blue": 1, + "green": 1, + "red": 1, + "x": 1, + "y": 1, + "z": 1 + }, + "emitOrientation": { + "w": 1, + "x": -1.52587890625e-05, + "y": -1.52587890625e-05, + "z": -1.52587890625e-05 + }, + "emitRate": 6, + "emitSpeed": 0, + "id": "{b310070f-6af8-4c1d-9ad7-ea1070b53763}", + "lastEdited": 1536093329670211, + "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", + "lifespan": 10, + "locked": true, + "maxParticles": 10, + "name": "Stars", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "particleRadius": 0.07000000029802322, + "polarFinish": 3.1415927410125732, + "position": { + "blue": 1.3712034225463867, + "green": 0.5220947265625, + "red": 2.6281180381774902, + "x": 2.6281180381774902, + "y": 0.5220947265625, + "z": 1.3712034225463867 + }, + "queryAACube": { + "scale": 22.932353973388672, + "x": -8.838058471679688, + "y": -10.944082260131836, + "z": -10.09497356414795 + }, + "radiusFinish": 0, + "radiusStart": 0, + "rotation": { + "w": 0.9852597713470459, + "x": -1.52587890625e-05, + "y": -0.17106890678405762, + "z": -7.62939453125e-05 + }, + "speedSpread": 0, + "spinFinish": null, + "spinStart": null, + "textures": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/star.png", + "type": "ParticleEffect", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}" + }, + { + "angularDamping": 0, + "clientOnly": false, + "color": { + "blue": 0, + "green": 0, + "red": 255 + }, + "created": "2018-09-04T20:35:23Z", + "dimensions": { + "blue": 0.20000000298023224, + "green": 0.20000000298023224, + "red": 0.20000000298023224, + "x": 0.20000000298023224, + "y": 0.20000000298023224, + "z": 0.20000000298023224 + }, + "id": "{7c24a30b-47d3-4cf6-af92-5a7959a3cb5d}", + "lastEdited": 1536093329671011, + "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", + "locked": true, + "name": "Particle Rotate", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 1.3116319179534912, + "green": 0, + "red": 2.705613613128662, + "x": 2.705613613128662, + "y": 0, + "z": 1.3116319179534912 + }, + "queryAACube": { + "scale": 0.3464101552963257, + "x": 2.5324084758758545, + "y": -0.17320507764816284, + "z": 1.1384267807006836 + }, + "rotation": { + "w": 0.9127794504165649, + "x": 0.2575265169143677, + "y": 0.15553522109985352, + "z": 0.2761729955673218 + }, + "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", + "scriptTimestamp": 1532724769253, + "shape": "Cube", + "type": "Box", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}", + "visible": false } ], - "Id": "{99bc5288-05fd-4d80-a406-a44c948f7066}", + "Id": "{c9a2e576-13f3-44fa-8d41-a466b33d16c6}", "Version": 93 -} \ No newline at end of file +} diff --git a/scripts/system/notifications.js b/scripts/system/notifications.js index 13d500b909..0778e2a44b 100644 --- a/scripts/system/notifications.js +++ b/scripts/system/notifications.js @@ -624,7 +624,7 @@ Controller.keyReleaseEvent.connect(keyReleaseEvent); Script.update.connect(update); Script.scriptEnding.connect(scriptEnding); - //Window.domainConnectionRefused.connect(onDomainConnectionRefused); + Window.domainConnectionRefused.connect(onDomainConnectionRefused); Window.stillSnapshotTaken.connect(onSnapshotTaken); Window.snapshot360Taken.connect(onSnapshotTaken); Window.processingGifStarted.connect(processingGif); From 7af69b54501f5989de5bab6d606d69021a9bdf56 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Tue, 4 Sep 2018 13:53:25 -0700 Subject: [PATCH 235/545] Check that a requested listened port is used in NodeList --- libraries/networking/src/LimitedNodeList.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index b6b2369703..db6ed15792 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -56,13 +56,20 @@ LimitedNodeList::LimitedNodeList(int socketListenPort, int dtlsListenPort) : qRegisterMetaType("ConnectionStep"); auto port = (socketListenPort != INVALID_PORT) ? socketListenPort : LIMITED_NODELIST_LOCAL_PORT.get(); _nodeSocket.bind(QHostAddress::AnyIPv4, port); - qCDebug(networking) << "NodeList socket is listening on" << _nodeSocket.localPort(); + quint16 assignedPort = _nodeSocket.localPort(); + if (socketListenPort != INVALID_PORT && socketListenPort != 0 && socketListenPort != assignedPort) { + qCCritical(networking) << "NodeList is unable to assign requested port of" << socketListenPort; + } + qCDebug(networking) << "NodeList socket is listening on" << assignedPort; if (dtlsListenPort != INVALID_PORT) { // only create the DTLS socket during constructor if a custom port is passed _dtlsSocket = new QUdpSocket(this); _dtlsSocket->bind(QHostAddress::AnyIPv4, dtlsListenPort); + if (dtlsListenPort != 0 && _dtlsSocket->localPort() != dtlsListenPort) { + qCDebug(networking) << "NodeList is unable to assign requested DTLS port of" << dtlsListenPort; + } qCDebug(networking) << "NodeList DTLS socket is listening on" << _dtlsSocket->localPort(); } From 002c6547ee182eb32b24e366a5c2811dd6bd9fb5 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Tue, 4 Sep 2018 14:08:13 -0700 Subject: [PATCH 236/545] entity script URL update --- interface/resources/serverless/redirect.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/resources/serverless/redirect.json b/interface/resources/serverless/redirect.json index 72c4abc16b..0f58574c1e 100644 --- a/interface/resources/serverless/redirect.json +++ b/interface/resources/serverless/redirect.json @@ -44,7 +44,7 @@ "y": -0.22495104372501373, "z": 0 }, - "script": "https://raw.githubusercontent.com/wayne-chen/hifi/404DomainRedirect/scripts/redirect/zoneTryAgainEntityScript.js", + "script": "https://hifi-content.s3.amazonaws.com/wayne/404redirectionScripts/zoneTryAgainEntityScript.js", "shapeType": "box", "type": "Zone", "userData": "{\"grabbableKey\":{\"grabbable\":false}}" @@ -88,7 +88,7 @@ "y": -0.36650121212005615, "z": 0 }, - "script": "https://raw.githubusercontent.com/wayne-chen/hifi/404DomainRedirect/scripts/redirect/zoneBackEntityScript.js", + "script": "https://hifi-content.s3.amazonaws.com/wayne/404redirectionScripts/zoneBackEntityScript.js", "shapeType": "box", "type": "Zone", "userData": "{\"grabbableKey\":{\"grabbable\":false}}" @@ -364,7 +364,7 @@ "y": 0.4179598093032837, "z": -0.0001068115234375 }, - "script": "https://raw.githubusercontent.com/wayne-chen/hifi/404DomainRedirect/scripts/redirect/backEntityScript.js", + "script": "https://hifi-content.s3.amazonaws.com/wayne/404redirectionScripts/backEntityScript.js", "scriptTimestamp": 1535751754379, "shapeType": "static-mesh", "type": "Model", @@ -454,7 +454,7 @@ "y": 0.5693598985671997, "z": -0.0001068115234375 }, - "script": "https://raw.githubusercontent.com/wayne-chen/hifi/404DomainRedirect/scripts/redirect/tryAgainEntityScript.js", + "script": "https://hifi-content.s3.amazonaws.com/wayne/404redirectionScripts/tryAgainEntityScript.js", "shapeType": "static-mesh", "type": "Model", "userData": "{\"grabbableKey\":{\"grabbable\":false}}" From e210fadc7cb599b9f6a72b5dade5398678ca51f7 Mon Sep 17 00:00:00 2001 From: Anthony Thibault Date: Tue, 4 Sep 2018 14:36:56 -0700 Subject: [PATCH 237/545] Fix for glitch when entering inAir state from takeoff. This was due to a frame lag of blend factor used for inAir blending. So the first frame the upward velocity would be 0, followed by 3.5 m/s the next frame. This is fixed by using the workingVelocity instead of _lastVelocity to drive the blend. --- libraries/animation/src/Rig.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index c3e679096b..13cf165dac 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -926,7 +926,7 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos // compute blend based on velocity const float JUMP_SPEED = 3.5f; - float alpha = glm::clamp(-_lastVelocity.y / JUMP_SPEED, -1.0f, 1.0f) + 1.0f; + float alpha = glm::clamp(-workingVelocity.y / JUMP_SPEED, -1.0f, 1.0f) + 1.0f; _animVars.set("inAirAlpha", alpha); } From 9e76c164ac76fcc6dfadb05b79da96a862188d97 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Tue, 4 Sep 2018 16:25:47 -0700 Subject: [PATCH 238/545] fix aabox operator+= --- libraries/shared/src/AABox.h | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/libraries/shared/src/AABox.h b/libraries/shared/src/AABox.h index e0bb1343f8..f41bb8a814 100644 --- a/libraries/shared/src/AABox.h +++ b/libraries/shared/src/AABox.h @@ -86,19 +86,12 @@ public: AABox clamp(float min, float max) const; inline AABox& operator+=(const glm::vec3& point) { - // Branchless version of: - //if (isInvalid()) { - // _corner = glm::min(_corner, point); - //} else { - // glm::vec3 maximum(_corner + _scale); - // _corner = glm::min(_corner, point); - // maximum = glm::max(maximum, point); - // _scale = maximum - _corner; - //} - float blend = (float)isInvalid(); - glm::vec3 maximumScale(glm::max(_scale, point - _corner)); + bool valid = !isInvalid(); + glm::vec3 maximum = glm::max(_corner + _scale, point); _corner = glm::min(_corner, point); - _scale = blend * _scale + (1.0f - blend) * maximumScale; + if (valid) { + _scale = maximum - _corner; + } return (*this); } @@ -136,7 +129,7 @@ public: static const glm::vec3 INFINITY_VECTOR; - bool isInvalid() const { return _corner == INFINITY_VECTOR; } + bool isInvalid() const { return _corner.x == std::numeric_limits::infinity(); } void clear() { _corner = INFINITY_VECTOR; _scale = glm::vec3(0.0f); } From 99e6e3d1128826f86ec529743032e8da6e2820ce Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Tue, 4 Sep 2018 17:18:26 -0700 Subject: [PATCH 239/545] Collision Pick added to teleport.js --- .../controllers/controllerModules/teleport.js | 77 +++++++++++++++---- 1 file changed, 61 insertions(+), 16 deletions(-) diff --git a/scripts/system/controllers/controllerModules/teleport.js b/scripts/system/controllers/controllerModules/teleport.js index e4dd1c43fa..c69382a47a 100644 --- a/scripts/system/controllers/controllerModules/teleport.js +++ b/scripts/system/controllers/controllerModules/teleport.js @@ -22,6 +22,7 @@ Script.include("/~/system/libraries/controllers.js"); (function() { // BEGIN LOCAL_SCOPE var TARGET_MODEL_URL = Script.resolvePath("../../assets/models/teleport-destination.fbx"); + var CANCEL_MODEL_URL = Script.resolvePath("../../assets/models/teleport-cancel.fbx"); var SEAT_MODEL_URL = Script.resolvePath("../../assets/models/teleport-seat.fbx"); var TARGET_MODEL_DIMENSIONS = { @@ -72,6 +73,12 @@ Script.include("/~/system/libraries/controllers.js"); alpha: 1, width: 0.025 }; + var cancelEnd = { + type: "model", + url: CANCEL_MODEL_URL, + dimensions: TARGET_MODEL_DIMENSIONS, + ignorePickIntersection: true + }; var teleportEnd = { type: "model", url: TARGET_MODEL_URL, @@ -84,18 +91,24 @@ Script.include("/~/system/libraries/controllers.js"); dimensions: TARGET_MODEL_DIMENSIONS, ignorePickIntersection: true }; - - - var teleportRenderStates = [{name: "cancel", path: cancelPath}, + + var collisionEnd = { + type: "sphere", + dimensions: {x: 0, y: 0, z: 0}, + ignorePickIntersection: true + }; + + var teleportRenderStates = [{name: "noend", path: cancelPath}, + {name: "cancel", path: cancelPath, end: cancelEnd}, {name: "teleport", path: teleportPath, end: teleportEnd}, - {name: "seat", path: seatPath, end: seatEnd}]; + {name: "seat", path: seatPath, end: seatEnd}, + {name: "invisible", end: collisionEnd}]; var DEFAULT_DISTANCE = 8.0; - var teleportDefaultRenderStates = [{name: "cancel", distance: DEFAULT_DISTANCE, path: cancelPath}]; + var teleportDefaultRenderStates = [{name: "noend", distance: DEFAULT_DISTANCE, path: cancelPath}]; var ignoredEntities = []; - var TELEPORTER_STATES = { IDLE: 'idle', TARGETTING: 'targetting', @@ -106,6 +119,7 @@ Script.include("/~/system/libraries/controllers.js"); NONE: 'none', // Not currently targetting anything INVISIBLE: 'invisible', // The current target is an invvsible surface INVALID: 'invalid', // The current target is invalid (wall, ceiling, etc.) + CANCEL: 'cancel', // Insufficient space to accommodate the avatar capsule SURFACE: 'surface', // The current target is a valid surface SEAT: 'seat' // The current target is a seat }; @@ -122,6 +136,9 @@ Script.include("/~/system/libraries/controllers.js"); this.state = TELEPORTER_STATES.IDLE; this.currentTarget = TARGET.INVALID; this.currentResult = null; + this.capsuleHeight = 2.0; + this.capsuleRadius = 0.25; + this.pickHeightOffset = 0.01; this.getOtherModule = function() { var otherModule = this.hand === RIGHT_HAND ? leftTeleporter : rightTeleporter; @@ -143,6 +160,7 @@ Script.include("/~/system/libraries/controllers.js"); defaultRenderStates: teleportDefaultRenderStates, maxDistance: 8.0 }); + this.teleportParabolaHandInvisible = Pointers.createPointer(PickType.Parabola, { joint: (_this.hand === RIGHT_HAND) ? "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" : "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND", dirOffset: { x: 0, y: 1, z: 0.1 }, @@ -157,6 +175,19 @@ Script.include("/~/system/libraries/controllers.js"); renderStates: teleportRenderStates, maxDistance: 8.0 }); + + this.teleportCollisionPick = Picks.createPick(PickType.Collision, { + enabled: true, + filter: Picks.PICK_ENTITIES + Picks.PICK_AVATARS, + shape: { + shapeType: "capsule-y", + dimensions: { x: _this.capsuleRadius * 2.0, y: _this.capsuleHeight - (_this.capsuleRadius * 2.0), z: _this.capsuleRadius * 2.0 } + }, + position: { x: 0, y: _this.pickHeightOffset + (_this.capsuleHeight * 0.5), z: 0 }, + parentID: Pointers.getPointerProperties(_this.teleportParabolaHandInvisible).renderStates["invisible"].end, + threshold: 0.05 + }); + this.teleportParabolaHeadVisible = Pointers.createPointer(PickType.Parabola, { joint: "Avatar", filter: Picks.PICK_ENTITIES, @@ -170,6 +201,7 @@ Script.include("/~/system/libraries/controllers.js"); defaultRenderStates: teleportDefaultRenderStates, maxDistance: 8.0 }); + this.teleportParabolaHeadInvisible = Pointers.createPointer(PickType.Parabola, { joint: "Avatar", filter: Picks.PICK_ENTITIES | Picks.PICK_INCLUDE_INVISIBLE, @@ -184,11 +216,14 @@ Script.include("/~/system/libraries/controllers.js"); }); this.cleanup = function() { - Pointers.removePointer(this.teleportParabolaHandVisible); - Pointers.removePointer(this.teleportParabolaHandInvisible); - Pointers.removePointer(this.teleportParabolaHeadVisible); - Pointers.removePointer(this.teleportParabolaHeadInvisible); + Pointers.removePointer(_this.teleportParabolaHandVisible); + Pointers.removePointer(_this.teleportParabolaHandInvisible); + Pointers.removePointer(_this.teleportParabolaHeadVisible); + Pointers.removePointer(_this.teleportParabolaHeadInvisible); + Picks.removePick(_this.teleportCollisionPick); }; + + // Picks.setIgnoreItems(_this.teleportCollisionPick, []); this.axisButtonStateX = 0; // Left/right axis button pressed. this.axisButtonStateY = 0; // Up/down axis button pressed. @@ -280,8 +315,9 @@ Script.include("/~/system/libraries/controllers.js"); } else { result = Pointers.getPrevPickResult(_this.teleportParabolaHandInvisible); } - - var teleportLocationType = getTeleportTargetType(result); + var collisionResult = Picks.getPrevPickResult(_this.teleportCollisionPick); + + var teleportLocationType = getTeleportTargetType(result, collisionResult); if (teleportLocationType === TARGET.INVISIBLE) { if (mode === 'head') { result = Pointers.getPrevPickResult(_this.teleportParabolaHeadVisible); @@ -293,11 +329,13 @@ Script.include("/~/system/libraries/controllers.js"); if (teleportLocationType === TARGET.NONE) { // Use the cancel default state - this.setTeleportState(mode, "cancel", ""); + this.setTeleportState(mode, "noend", ""); } else if (teleportLocationType === TARGET.INVALID || teleportLocationType === TARGET.INVISIBLE) { - this.setTeleportState(mode, "", "cancel"); + this.setTeleportState(mode, "", "noend"); + } else if (teleportLocationType === TARGET.CANCEL) { + this.setTeleportState(mode, "cancel", "invisible"); } else if (teleportLocationType === TARGET.SURFACE) { - this.setTeleportState(mode, "teleport", ""); + this.setTeleportState(mode, "teleport", "invisible"); } else if (teleportLocationType === TARGET.SEAT) { this.setTeleportState(mode, "", "seat"); } @@ -355,6 +393,7 @@ Script.include("/~/system/libraries/controllers.js"); // related to repositioning the avatar after you teleport var FOOT_JOINT_NAMES = ["RightToe_End", "RightToeBase", "RightFoot"]; var DEFAULT_ROOT_TO_FOOT_OFFSET = 0.5; + function getAvatarFootOffset() { // find a valid foot jointIndex @@ -395,7 +434,8 @@ Script.include("/~/system/libraries/controllers.js"); // than MAX_ANGLE_FROM_UP_TO_TELEPORT degrees from your avatar's up, then // you can't teleport there. var MAX_ANGLE_FROM_UP_TO_TELEPORT = 70; - function getTeleportTargetType(result) { + + function getTeleportTargetType(result, collisionResult) { if (result.type === Picks.INTERSECTED_NONE) { return TARGET.NONE; } @@ -421,6 +461,11 @@ Script.include("/~/system/libraries/controllers.js"); if (angle > MAX_ANGLE_FROM_UP_TO_TELEPORT) { return TARGET.INVALID; } else { + if (collisionResult.collisionRegion != undefined) { + if (collisionResult.intersects) { + return TARGET.CANCEL; + } + } return TARGET.SURFACE; } } From adcabf52c5f2945ce368a39b194190a86f698902 Mon Sep 17 00:00:00 2001 From: sam gateau Date: Tue, 4 Sep 2018 17:33:18 -0700 Subject: [PATCH 240/545] Refactoring the FBXReader_MEsh.cpp for better interleaving --- libraries/fbx/src/FBXReader_Mesh.cpp | 226 +++++++++++++-------------- 1 file changed, 110 insertions(+), 116 deletions(-) diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index e6d9321fb5..4ecca2b234 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -585,16 +585,9 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { FBXMesh& fbxMesh = extractedMesh; graphics::MeshPointer mesh(new graphics::Mesh()); - // bool blendShapes = !fbxMesh.blendshapes.empty(); + bool hasBlendShapes = !fbxMesh.blendshapes.empty(); int numVerts = extractedMesh.vertices.size(); - // Grab the vertices in a buffer - auto vb = std::make_shared(); - vb->setData(extractedMesh.vertices.size() * sizeof(glm::vec3), - (const gpu::Byte*) extractedMesh.vertices.data()); - gpu::BufferView vbv(vb, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ)); - // mesh->setVertexBuffer(vbv); - if (!fbxMesh.normals.empty() && fbxMesh.tangents.empty()) { // Fill with a dummy value to force tangents to be present if there are normals fbxMesh.tangents.reserve(fbxMesh.normals.size()); @@ -609,50 +602,61 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { } } - // evaluate all attribute channels sizes - const int normalsSize = fbxMesh.normals.size() * sizeof(NormalType); - const int tangentsSize = fbxMesh.tangents.size() * sizeof(NormalType); + // evaluate all attribute elements and data sizes + + // Position is a vec3 + const auto positionElement = gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ); + const int positionsSize = numVerts * positionElement.getSize(); + + // Normal and tangent are always there together packed in normalized xyz32bits word (times 2) + const auto normalElement = FBX_NORMAL_ELEMENT; + const int normalsSize = fbxMesh.normals.size() * normalElement.getSize(); + const int tangentsSize = fbxMesh.tangents.size() * normalElement.getSize(); // If there are normals then there should be tangents - assert(normalsSize <= tangentsSize); if (tangentsSize > normalsSize) { qWarning() << "Unexpected tangents in " << url; } const auto normalsAndTangentsSize = normalsSize + tangentsSize; - // const int normalsAndTangentsStride = 2 * sizeof(NormalType); - const int colorsSize = fbxMesh.colors.size() * sizeof(ColorType); + const int normalsAndTangentsStride = 2 * normalElement.getSize(); + + // Color attrib + const auto colorElement = FBX_COLOR_ELEMENT; + const int colorsSize = fbxMesh.colors.size() * colorElement.getSize(); + // Texture coordinates are stored in 2 half floats - const int texCoordsSize = fbxMesh.texCoords.size() * sizeof(vec2h); - const int texCoords1Size = fbxMesh.texCoords1.size() * sizeof(vec2h); + const auto texCoordsElement = gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV); + const int texCoordsSize = fbxMesh.texCoords.size() * texCoordsElement.getSize(); + const int texCoords1Size = fbxMesh.texCoords1.size() * texCoordsElement.getSize(); - int clusterIndicesSize = fbxMesh.clusterIndices.size() * sizeof(uint8_t); - if (fbxMesh.clusters.size() > UINT8_MAX) { - // we need 16 bits instead of just 8 for clusterIndices - clusterIndicesSize *= 2; - } + // Support for 4 skinning clusters: + // 4 Indices are uint8 ideally, uint16 if more than 256. + const auto clusterIndiceElement = (fbxMesh.clusters.size() < UINT8_MAX ? gpu::Element(gpu::VEC4, gpu::UINT8, gpu::XYZW) : gpu::Element(gpu::VEC4, gpu::UINT16, gpu::XYZW)); + // 4 Weights are normalized 16bits + const auto clusterWeightElement = gpu::Element(gpu::VEC4, gpu::NUINT16, gpu::XYZW); - const int clusterWeightsSize = fbxMesh.clusterWeights.size() * sizeof(uint16_t); + // Cluster indices and weights must be the same sizes + const int NUM_CLUSTERS_PER_VERT = 4; + const int numVertClusters = (fbxMesh.clusterIndices.size() == fbxMesh.clusterWeights.size() ? fbxMesh.clusterIndices.size() / NUM_CLUSTERS_PER_VERT : 0); + const int clusterIndicesSize = numVertClusters * clusterIndiceElement.getSize(); + const int clusterWeightsSize = numVertClusters * clusterWeightElement.getSize(); - // Normals and tangents are interleaved - const int normalsOffset = 0; - // const int tangentsOffset = normalsOffset + sizeof(NormalType); - const int totalNTSize = normalsOffset + normalsSize + tangentsSize; - //const int colorsOffset = normalsOffset + normalsSize + tangentsSize; - - const int colorsOffset = 0; + // Decide on where to put what seequencially in a big buffer: + const int positionsOffset = 0; + const int normalsAndTangentsOffset = positionsOffset + positionsSize; + const int colorsOffset = normalsAndTangentsOffset + normalsAndTangentsSize; const int texCoordsOffset = colorsOffset + colorsSize; const int texCoords1Offset = texCoordsOffset + texCoordsSize; const int clusterIndicesOffset = texCoords1Offset + texCoords1Size; const int clusterWeightsOffset = clusterIndicesOffset + clusterIndicesSize; - const int totalAttributeSize = clusterWeightsOffset + clusterWeightsSize; + const int totalVertsSize = clusterWeightsOffset + clusterWeightsSize; - // Copy all attribute data in a single attribute buffer + // Copy all vertex data in a single buffer + auto vertBuffer = std::make_shared(); + vertBuffer->resize(totalVertsSize); - auto attribNTBuffer = std::make_shared(); - attribNTBuffer->resize(totalNTSize); - - auto attribBuffer = std::make_shared(); - attribBuffer->resize(totalAttributeSize); + // First positions + vertBuffer->setSubData(positionsOffset, positionsSize, (const gpu::Byte*) extractedMesh.vertices.data()); // Interleave normals and tangents if (normalsSize > 0) { @@ -660,8 +664,8 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { normalsAndTangents.reserve(fbxMesh.normals.size() + fbxMesh.tangents.size()); for (auto normalIt = fbxMesh.normals.constBegin(), tangentIt = fbxMesh.tangents.constBegin(); - normalIt != fbxMesh.normals.constEnd(); - ++normalIt, ++tangentIt) { + normalIt != fbxMesh.normals.constEnd(); + ++normalIt, ++tangentIt) { #if FBX_PACK_NORMALS const auto normal = normalizeDirForPacking(*normalIt); const auto tangent = normalizeDirForPacking(*tangentIt); @@ -674,10 +678,10 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { normalsAndTangents.push_back(packedNormal); normalsAndTangents.push_back(packedTangent); } - attribNTBuffer->setSubData(normalsOffset, normalsAndTangentsSize, (const gpu::Byte*) normalsAndTangents.data()); + vertBuffer->setSubData(normalsAndTangentsOffset, normalsAndTangentsSize, (const gpu::Byte*) normalsAndTangents.data()); } - + // Pack colors if (colorsSize > 0) { #if FBX_PACK_COLORS std::vector colors; @@ -686,12 +690,13 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { for (const auto& color : fbxMesh.colors) { colors.push_back(glm::packUnorm4x8(glm::vec4(color, 1.0f))); } - attribBuffer->setSubData(colorsOffset, colorsSize, (const gpu::Byte*) colors.data()); + vertBuffer->setSubData(colorsOffset, colorsSize, (const gpu::Byte*) colors.data()); #else - attribBuffer->setSubData(colorsOffset, colorsSize, (const gpu::Byte*) fbxMesh.colors.constData()); + vertBuffer->setSubData(colorsOffset, colorsSize, (const gpu::Byte*) fbxMesh.colors.constData()); #endif } + // Pack Texcoords 0 and 1 (if exists) if (texCoordsSize > 0) { QVector texCoordData; texCoordData.reserve(fbxMesh.texCoords.size()); @@ -702,9 +707,8 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { texCoordVec2h.y = glm::detail::toFloat16(texCoordVec2f.y); texCoordData.push_back(texCoordVec2h); } - attribBuffer->setSubData(texCoordsOffset, texCoordsSize, (const gpu::Byte*) texCoordData.constData()); + vertBuffer->setSubData(texCoordsOffset, texCoordsSize, (const gpu::Byte*) texCoordData.constData()); } - if (texCoords1Size > 0) { QVector texCoordData; texCoordData.reserve(fbxMesh.texCoords1.size()); @@ -715,100 +719,91 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { texCoordVec2h.y = glm::detail::toFloat16(texCoordVec2f.y); texCoordData.push_back(texCoordVec2h); } - attribBuffer->setSubData(texCoords1Offset, texCoords1Size, (const gpu::Byte*) texCoordData.constData()); + vertBuffer->setSubData(texCoords1Offset, texCoords1Size, (const gpu::Byte*) texCoordData.constData()); } - if (fbxMesh.clusters.size() < UINT8_MAX) { - // yay! we can fit the clusterIndices within 8-bits - int32_t numIndices = fbxMesh.clusterIndices.size(); - QVector clusterIndices; - clusterIndices.resize(numIndices); - for (int32_t i = 0; i < numIndices; ++i) { - assert(fbxMesh.clusterIndices[i] <= UINT8_MAX); - clusterIndices[i] = (uint8_t)(fbxMesh.clusterIndices[i]); + // Clusters data + if (clusterIndicesSize > 0) { + if (fbxMesh.clusters.size() < UINT8_MAX) { + // yay! we can fit the clusterIndices within 8-bits + int32_t numIndices = fbxMesh.clusterIndices.size(); + QVector clusterIndices; + clusterIndices.resize(numIndices); + for (int32_t i = 0; i < numIndices; ++i) { + assert(fbxMesh.clusterIndices[i] <= UINT8_MAX); + clusterIndices[i] = (uint8_t)(fbxMesh.clusterIndices[i]); + } + vertBuffer->setSubData(clusterIndicesOffset, clusterIndicesSize, (const gpu::Byte*) clusterIndices.constData()); + } + else { + vertBuffer->setSubData(clusterIndicesOffset, clusterIndicesSize, (const gpu::Byte*) fbxMesh.clusterIndices.constData()); } - attribBuffer->setSubData(clusterIndicesOffset, clusterIndicesSize, (const gpu::Byte*) clusterIndices.constData()); - } else { - attribBuffer->setSubData(clusterIndicesOffset, clusterIndicesSize, (const gpu::Byte*) fbxMesh.clusterIndices.constData()); } - attribBuffer->setSubData(clusterWeightsOffset, clusterWeightsSize, (const gpu::Byte*) fbxMesh.clusterWeights.constData()); + if (clusterWeightsSize > 0) { + vertBuffer->setSubData(clusterWeightsOffset, clusterWeightsSize, (const gpu::Byte*) fbxMesh.clusterWeights.constData()); + } + + // Now we decide on how to interleave the attributes and provide the vertices among bufers: + // Aka the Vertex format auto vf = std::make_shared(); - auto vbs = std::make_shared(); - - gpu::Offset buf0Offset = 12; - vf->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ)); - vbs->addBuffer(vb, 0, buf0Offset); + gpu::Offset buf0Offset = 0; + vf->setAttribute(gpu::Stream::POSITION, 0, positionElement); + buf0Offset += positionElement.getSize(); gpu::Offset buf1Offset = 0; if (normalsSize) { - /* mesh->addAttribute(gpu::Stream::NORMAL, - graphics::BufferView(attribBuffer, normalsOffset, normalsAndTangentsSize, - normalsAndTangentsStride, FBX_NORMAL_ELEMENT)); - mesh->addAttribute(gpu::Stream::TANGENT, - graphics::BufferView(attribBuffer, tangentsOffset, normalsAndTangentsSize, - normalsAndTangentsStride, FBX_NORMAL_ELEMENT)); -*/ - vf->setAttribute(gpu::Stream::NORMAL, 1, FBX_NORMAL_ELEMENT, 0); - vf->setAttribute(gpu::Stream::TANGENT, 1, FBX_NORMAL_ELEMENT, 4); - buf1Offset = 8; - vbs->addBuffer(attribNTBuffer, 0, buf1Offset); + vf->setAttribute(gpu::Stream::NORMAL, 1, normalElement, buf1Offset); + buf1Offset = normalElement.getSize(); + vf->setAttribute(gpu::Stream::TANGENT, 1, normalElement, buf1Offset); + buf1Offset = normalElement.getSize(); } - gpu::Offset buf2Offset = 0; + gpu::Offset buf2Offset = (0); if (colorsSize) { - /* mesh->addAttribute(gpu::Stream::COLOR, - graphics::BufferView(attribBuffer, colorsOffset, colorsSize, FBX_COLOR_ELEMENT)); -*/ - vf->setAttribute(gpu::Stream::COLOR, 2, FBX_COLOR_ELEMENT, buf2Offset); - buf2Offset += 4; + vf->setAttribute(gpu::Stream::COLOR, 2, colorElement, buf2Offset); + buf2Offset += colorElement.getSize(); } if (texCoordsSize) { - /* mesh->addAttribute(gpu::Stream::TEXCOORD, - graphics::BufferView( attribBuffer, texCoordsOffset, texCoordsSize, - gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV))); - */ vf->setAttribute(gpu::Stream::TEXCOORD, 2, gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV), buf2Offset); - buf2Offset += 4; + vf->setAttribute(gpu::Stream::TEXCOORD, 2, texCoordsElement, buf2Offset); + buf2Offset += texCoordsElement.getSize(); } if (texCoords1Size) { - /* mesh->addAttribute( gpu::Stream::TEXCOORD1, - graphics::BufferView(attribBuffer, texCoords1Offset, texCoords1Size, - gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV))); - */ vf->setAttribute(gpu::Stream::TEXCOORD1, 2, gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV), buf2Offset); - buf2Offset += 4; - } else if (texCoordsSize) { - /* mesh->addAttribute(gpu::Stream::TEXCOORD1, - graphics::BufferView(attribBuffer, texCoordsOffset, texCoordsSize, - gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV))); - */ vf->setAttribute(gpu::Stream::TEXCOORD1, 2, gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV), buf2Offset - 4); + vf->setAttribute(gpu::Stream::TEXCOORD1, 2, texCoordsElement, buf2Offset); + buf2Offset += texCoordsElement.getSize(); + } + else if (texCoordsSize) { + vf->setAttribute(gpu::Stream::TEXCOORD1, 2, texCoordsElement, buf2Offset - texCoordsElement.getSize()); } - if (clusterIndicesSize) { - if (fbxMesh.clusters.size() < UINT8_MAX) { - /* mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, - graphics::BufferView(attribBuffer, clusterIndicesOffset, clusterIndicesSize, - gpu::Element(gpu::VEC4, gpu::UINT8, gpu::XYZW))); -*/ - vf->setAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, 2, gpu::Element(gpu::VEC4, gpu::UINT8, gpu::XYZW), buf2Offset); - buf2Offset += 4; - - } else { - /* mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, - graphics::BufferView(attribBuffer, clusterIndicesOffset, clusterIndicesSize, - gpu::Element(gpu::VEC4, gpu::UINT16, gpu::XYZW))); - */ vf->setAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, 2, gpu::Element(gpu::VEC4, gpu::UINT16, gpu::XYZW), buf2Offset); - buf2Offset += 8; - } + vf->setAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, 2, clusterIndiceElement, buf2Offset); + buf2Offset += clusterIndiceElement.getSize(); } if (clusterWeightsSize) { - /* mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, - graphics::BufferView(attribBuffer, clusterWeightsOffset, clusterWeightsSize, - gpu::Element(gpu::VEC4, gpu::NUINT16, gpu::XYZW))); - */ vf->setAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, 2, gpu::Element(gpu::VEC4, gpu::NUINT16, gpu::XYZW), buf2Offset); - buf2Offset += 8; + vf->setAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, 2, clusterWeightElement, buf2Offset); + buf2Offset += clusterWeightElement.getSize(); } + auto vbs = std::make_shared(); + + + auto vb = std::make_shared(); + vb->setData(extractedMesh.vertices.size() * sizeof(glm::vec3), + (const gpu::Byte*) extractedMesh.vertices.data()); + gpu::BufferView vbv(vb, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ)); + vbs->addBuffer(vb, 0, buf0Offset); + + auto attribNTBuffer = std::make_shared(); + attribNTBuffer->resize(totalNTSize); + + auto attribBuffer = std::make_shared(); + attribBuffer->resize(totalAttributeSize); + + + { + vbs->addBuffer(attribNTBuffer, 0, buf1Offset); + auto vColorOffset = 0; auto vColorSize = colorsSize / numVerts; @@ -848,7 +843,6 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { vbs->addBuffer(attribBuffer, 0, vStride); } - mesh->setVertexFormatAndStream(vf, vbs); unsigned int totalIndices = 0; From 9e0fa08cf12af8009328dbe1a70506099b92043f Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Tue, 4 Sep 2018 17:46:23 -0700 Subject: [PATCH 241/545] adding property to location, updating domain --- interface/resources/serverless/redirect.json | 1317 +++++++----------- interface/src/Application.cpp | 2 + libraries/networking/src/AddressManager.cpp | 4 +- libraries/networking/src/AddressManager.h | 38 +- libraries/networking/src/DomainHandler.cpp | 1 + libraries/networking/src/DomainHandler.h | 2 + 6 files changed, 545 insertions(+), 819 deletions(-) diff --git a/interface/resources/serverless/redirect.json b/interface/resources/serverless/redirect.json index 0f58574c1e..f983a7ffef 100644 --- a/interface/resources/serverless/redirect.json +++ b/interface/resources/serverless/redirect.json @@ -9,7 +9,7 @@ "clientOnly": false, "collidesWith": "static,dynamic,kinematic,otherAvatar,", "collisionMask": 23, - "created": "2018-09-04T20:35:23Z", + "created": "2018-09-05T00:40:03Z", "dimensions": { "blue": 0.8660923838615417, "green": 1.921838402748108, @@ -18,25 +18,25 @@ "y": 1.921838402748108, "z": 0.8660923838615417 }, - "id": "{3889145e-9db2-46dc-9765-9ba7594457dc}", - "lastEdited": 1536093329670067, - "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", + "id": "{781e26c7-ecfa-44b2-b7ef-4e3278787fbc}", + "lastEdited": 1536108183362142, + "lastEditedBy": "{4656d4a8-5e61-4230-ab34-2888d7945bd6}", "locked": true, "name": "Try Again Zone", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": { - "blue": 4.524896621704102, - "green": 1.9289360046386719, - "red": 2.893861770629883, - "x": 2.893861770629883, - "y": 1.9289360046386719, - "z": 4.524896621704102 + "blue": 4.225754737854004, + "green": 1.7677892446517944, + "red": 2.778148889541626, + "x": 2.778148889541626, + "y": 1.7677892446517944, + "z": 4.225754737854004 }, "queryAACube": { "scale": 2.4632973670959473, - "x": 1.6622130870819092, - "y": 0.6972873210906982, - "z": 3.293247938156128 + "x": 1.5465002059936523, + "y": 0.5361405611038208, + "z": 2.9941060543060303 }, "rotation": { "w": 0.9743700623512268, @@ -50,244 +50,13 @@ "userData": "{\"grabbableKey\":{\"grabbable\":false}}" }, { - "clientOnly": false, - "collidesWith": "static,dynamic,kinematic,otherAvatar,", - "collisionMask": 23, - "created": "2018-09-04T20:35:23Z", - "dimensions": { - "blue": 1.159199833869934, - "green": 2.8062009811401367, - "red": 1.6216505765914917, - "x": 1.6216505765914917, - "y": 2.8062009811401367, - "z": 1.159199833869934 - }, - "id": "{8facc8e1-bc17-4460-8a9c-868b07c1b387}", - "lastEdited": 1536093329669913, - "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", - "locked": true, - "name": "Back Zone", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 1.8632707595825195, - "green": 1.8022732734680176, - "red": 3.3276727199554443, - "x": 3.3276727199554443, - "y": 1.8022732734680176, - "z": 1.8632707595825195 - }, - "queryAACube": { - "scale": 3.4421300888061523, - "x": 1.6066076755523682, - "y": 0.0812082290649414, - "z": 0.14220571517944336 - }, - "rotation": { - "w": 0.9304176568984985, - "x": 0, - "y": -0.36650121212005615, - "z": 0 - }, - "script": "https://hifi-content.s3.amazonaws.com/wayne/404redirectionScripts/zoneBackEntityScript.js", - "shapeType": "box", - "type": "Zone", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}" - }, - { - "angularDamping": 0, "clientOnly": false, "color": { "blue": 0, "green": 0, "red": 255 }, - "created": "2018-09-04T20:35:23Z", - "dimensions": { - "blue": 0.20000000298023224, - "green": 0.20000000298023224, - "red": 0.20000000298023224, - "x": 0.20000000298023224, - "y": 0.20000000298023224, - "z": 0.20000000298023224 - }, - "id": "{ed4142db-f3c9-441b-9091-cd1755b6aeb1}", - "lastEdited": 1536093329672493, - "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", - "locked": true, - "name": "Particle Rotate", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 1.3116319179534912, - "green": 0.15618896484375, - "red": 2.705613613128662, - "x": 2.705613613128662, - "y": 0.15618896484375, - "z": 1.3116319179534912 - }, - "queryAACube": { - "scale": 0.3464101552963257, - "x": 2.5324084758758545, - "y": -0.017016112804412842, - "z": 1.1384267807006836 - }, - "rotation": { - "w": 0.46953535079956055, - "x": -0.16719311475753784, - "y": -0.7982757091522217, - "z": 0.3380941152572632 - }, - "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", - "scriptTimestamp": 1532724769253, - "shape": "Cube", - "type": "Box", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}", - "visible": false - }, - { - "clientOnly": false, - "color": { - "blue": 0, - "green": 0, - "red": 0 - }, - "created": "2018-09-04T20:35:23Z", - "dimensions": { - "blue": 11.117486953735352, - "green": 3.580313205718994, - "red": 0.20000000298023224, - "x": 0.20000000298023224, - "y": 3.580313205718994, - "z": 11.117486953735352 - }, - "id": "{d49f29ca-72b6-473d-917c-f7bf7d66f219}", - "lastEdited": 1536093329670344, - "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", - "locked": true, - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 0, - "green": 1.1583251953125, - "red": 4.971565246582031, - "x": 4.971565246582031, - "y": 1.1583251953125, - "z": 0 - }, - "queryAACube": { - "scale": 11.681488037109375, - "x": -0.8691787719726562, - "y": -4.6824188232421875, - "z": -5.8407440185546875 - }, - "rotation": { - "w": 0.8637980222702026, - "x": -4.57763671875e-05, - "y": 0.5038070678710938, - "z": -1.52587890625e-05 - }, - "shape": "Cube", - "type": "Box", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}", - "visible": false - }, - { - "clientOnly": false, - "created": "2018-09-04T20:35:23Z", - "dimensions": { - "blue": 0.06014331430196762, - "green": 2.582186460494995, - "red": 2.582186698913574, - "x": 2.582186698913574, - "y": 2.582186460494995, - "z": 0.06014331430196762 - }, - "id": "{6ccf519b-4e0b-4c23-a51b-305d0a64ab06}", - "lastEdited": 1536093329671943, - "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", - "locked": true, - "modelURL": "http://hifi-content.s3.amazonaws.com/alexia/LoadingScreens/oopsDialog.fbx", - "name": "Oops Dialog", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 1.45927095413208, - "green": 1.6763916015625, - "red": 0, - "x": 0, - "y": 1.6763916015625, - "z": 1.45927095413208 - }, - "queryAACube": { - "scale": 3.6522583961486816, - "x": -1.8261291980743408, - "y": -0.14973759651184082, - "z": -0.36685824394226074 - }, - "rotation": { - "w": 0.8684672117233276, - "x": -4.57763671875e-05, - "y": 0.4957197904586792, - "z": -7.62939453125e-05 - }, - "type": "Model", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}" - }, - { - "angularDamping": 0, - "clientOnly": false, - "color": { - "blue": 0, - "green": 0, - "red": 255 - }, - "created": "2018-09-04T20:35:23Z", - "dimensions": { - "blue": 0.20000000298023224, - "green": 0.20000000298023224, - "red": 0.20000000298023224, - "x": 0.20000000298023224, - "y": 0.20000000298023224, - "z": 0.20000000298023224 - }, - "id": "{625c95a4-1592-4996-bd48-7aa3fdbe6aee}", - "lastEdited": 1536093329671797, - "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", - "locked": true, - "name": "Particle Rotate", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 1.3116319179534912, - "green": 0.0772705078125, - "red": 2.705613613128662, - "x": 2.705613613128662, - "y": 0.0772705078125, - "z": 1.3116319179534912 - }, - "queryAACube": { - "scale": 0.3464101552963257, - "x": 2.5324084758758545, - "y": -0.09593456983566284, - "z": 1.1384267807006836 - }, - "rotation": { - "w": -0.38777750730514526, - "x": -0.37337303161621094, - "y": -0.8409399390220642, - "z": 0.055222392082214355 - }, - "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", - "scriptTimestamp": 1532724769253, - "shape": "Cube", - "type": "Box", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}", - "visible": false - }, - { - "clientOnly": false, - "color": { - "blue": 0, - "green": 0, - "red": 255 - }, - "created": "2018-09-04T20:35:23Z", + "created": "2018-09-05T00:40:03Z", "dimensions": { "blue": 8.645400047302246, "green": 0.20000000298023224, @@ -296,23 +65,24 @@ "y": 0.20000000298023224, "z": 8.645400047302246 }, - "id": "{d356bb44-7888-476a-821e-961ae7d9330e}", - "lastEdited": 1536093329671479, - "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", + "id": "{e44fb546-b34a-4966-9b11-73556f800d21}", + "lastEdited": 1536107948776951, + "lastEditedBy": "{ce82d352-3002-44ae-9b76-66492989a1db}", "locked": true, + "name": "ceiling", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": { "blue": 4.846520900726318, - "green": 3.0651936531066895, - "red": 5.746071815490723, - "x": 5.746071815490723, - "y": 3.0651936531066895, + "green": 2.912982940673828, + "red": 5.739595890045166, + "x": 5.739595890045166, + "y": 2.912982940673828, "z": 4.846520900726318 }, "queryAACube": { "scale": 21.812576293945312, - "x": -5.160216331481934, - "y": -7.841094493865967, + "x": -5.16669225692749, + "y": -7.993305206298828, "z": -6.059767246246338 }, "rotation": { @@ -328,46 +98,48 @@ }, { "clientOnly": false, - "created": "2018-09-04T20:35:23Z", - "dimensions": { - "blue": 2.1097896099090576, - "green": 0.04847164824604988, - "red": 1.458284616470337, - "x": 1.458284616470337, - "y": 0.04847164824604988, - "z": 2.1097896099090576 + "color": { + "blue": 0, + "green": 0, + "red": 0 }, - "id": "{737f1b31-0342-4764-89fb-2ef7ddf83983}", - "lastEdited": 1536093329672351, - "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", + "created": "2018-09-05T00:40:03Z", + "dimensions": { + "blue": 6.9401350021362305, + "green": 0.04553089290857315, + "red": 7.004304885864258, + "x": 7.004304885864258, + "y": 0.04553089290857315, + "z": 6.9401350021362305 + }, + "id": "{8cd93fe5-16c0-44b7-b1e9-e7e06c4e9228}", + "lastEdited": 1536107948774796, + "lastEditedBy": "{4eecd88f-ef9b-4a83-bb9a-7f7496209c6b}", "locked": true, - "modelURL": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/portal2.fbx", - "name": "Back", + "name": "floor", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": { - "blue": 1.5835940837860107, - "green": 0.2467041015625, - "red": 3.0345542430877686, - "x": 3.0345542430877686, - "y": 0.2467041015625, - "z": 1.5835940837860107 + "blue": 3.6175529956817627, + "green": 0, + "red": 4.102385997772217, + "x": 4.102385997772217, + "y": 0, + "z": 3.6175529956817627 }, "queryAACube": { - "scale": 2.5651814937591553, - "x": 1.751963496208191, - "y": -1.0358866453170776, - "z": 0.3010033369064331 + "scale": 9.860417366027832, + "x": -0.8278226852416992, + "y": -4.930208683013916, + "z": -1.3126556873321533 }, "rotation": { - "w": 0.9084458351135254, - "x": -1.52587890625e-05, - "y": 0.4179598093032837, - "z": -0.0001068115234375 + "w": 0.8660253882408142, + "x": -1.5922749298624694e-05, + "y": 0.5, + "z": -4.572480611386709e-05 }, - "script": "https://hifi-content.s3.amazonaws.com/wayne/404redirectionScripts/backEntityScript.js", - "scriptTimestamp": 1535751754379, - "shapeType": "static-mesh", - "type": "Model", + "shape": "Cube", + "type": "Box", "userData": "{\"grabbableKey\":{\"grabbable\":false}}" }, { @@ -377,7 +149,7 @@ "green": 0, "red": 0 }, - "created": "2018-09-04T20:35:23Z", + "created": "2018-09-05T00:40:03Z", "dimensions": { "blue": 11.117486953735352, "green": 3.580313205718994, @@ -386,29 +158,77 @@ "y": 3.580313205718994, "z": 11.117486953735352 }, - "id": "{87f734c8-37bb-4ac0-b300-5028f7fe6f9d}", - "lastEdited": 1536093329670472, - "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", + "id": "{147272dc-a344-4171-9621-efc1c2095997}", + "lastEdited": 1536107948776823, + "lastEditedBy": "{ce82d352-3002-44ae-9b76-66492989a1db}", "locked": true, + "name": "leftWall", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": { - "blue": 2.662257671356201, - "green": 1.1585893630981445, - "red": 1.493349552154541, - "x": 1.493349552154541, - "y": 1.1585893630981445, - "z": 2.662257671356201 + "blue": 6.1806135177612305, + "green": 1.0066027641296387, + "red": 1.4690406322479248, + "x": 1.4690406322479248, + "y": 1.0066027641296387, + "z": 6.1806135177612305 }, "queryAACube": { "scale": 11.681488037109375, - "x": -4.3473944664001465, - "y": -4.682154655456543, - "z": -3.1784863471984863 + "x": -4.371703147888184, + "y": -4.834141254425049, + "z": 0.33986949920654297 }, "rotation": { - "w": 0.9666743278503418, + "w": 0.8637980222702026, "x": -4.57763671875e-05, - "y": -0.2560006380081177, + "y": 0.5038070678710938, + "z": -1.52587890625e-05 + }, + "shape": "Cube", + "type": "Box", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}", + "visible": false + }, + { + "clientOnly": false, + "color": { + "blue": 0, + "green": 0, + "red": 0 + }, + "created": "2018-09-05T00:40:03Z", + "dimensions": { + "blue": 11.117486953735352, + "green": 3.580313205718994, + "red": 0.20000000298023224, + "x": 0.20000000298023224, + "y": 3.580313205718994, + "z": 11.117486953735352 + }, + "id": "{5f2b89b8-47e3-4915-a966-d46307a40f06}", + "lastEdited": 1536107948774605, + "lastEditedBy": "{ce82d352-3002-44ae-9b76-66492989a1db}", + "locked": true, + "name": "backWall", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 5.268576622009277, + "green": 1.0066027641296387, + "red": 6.093774318695068, + "x": 6.093774318695068, + "y": 1.0066027641296387, + "z": 5.268576622009277 + }, + "queryAACube": { + "scale": 11.681488037109375, + "x": 0.25303030014038086, + "y": -4.834141254425049, + "z": -0.5721673965454102 + }, + "rotation": { + "w": 0.9662165641784668, + "x": -4.57763671875e-05, + "y": -0.2576791048049927, "z": 1.52587890625e-05 }, "shape": "Cube", @@ -418,45 +238,43 @@ }, { "clientOnly": false, - "created": "2018-09-04T20:35:23Z", + "created": "2018-09-05T00:40:03Z", "dimensions": { - "blue": 2.1097896099090576, - "green": 0.04847164824604988, - "red": 1.458284616470337, - "x": 1.458284616470337, - "y": 0.04847164824604988, - "z": 2.1097896099090576 + "blue": 14.40000057220459, + "green": 14.40000057220459, + "red": 14.40000057220459, + "x": 14.40000057220459, + "y": 14.40000057220459, + "z": 14.40000057220459 }, - "id": "{9584bb57-b543-4d2b-af98-f3de618eef19}", - "lastEdited": 1536093329672070, + "id": "{baf96345-8f68-4068-af4c-3c690035852a}", + "lastEdited": 1536107948775591, "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", "locked": true, - "modelURL": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/portal1.fbx", - "name": "Try Again", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": { - "blue": 3.946338653564453, - "green": 0.2467041015625, - "red": 1.6013128757476807, - "x": 1.6013128757476807, - "y": 0.2467041015625, - "z": 3.946338653564453 + "blue": 2.3440732955932617, + "green": 1.6162219047546387, + "red": 1.8748211860656738, + "x": 1.8748211860656738, + "y": 1.6162219047546387, + "z": 2.3440732955932617 }, "queryAACube": { - "scale": 2.5651814937591553, - "x": 0.318722128868103, - "y": -1.0358866453170776, - "z": 2.663747787475586 + "scale": 24.9415340423584, + "x": -10.595945358276367, + "y": -10.854545593261719, + "z": -10.126693725585938 }, "rotation": { - "w": 0.8220492601394653, + "w": 0.8697794675827026, "x": -1.52587890625e-05, - "y": 0.5693598985671997, - "z": -0.0001068115234375 + "y": 0.4933699369430542, + "z": -4.57763671875e-05 }, - "script": "https://hifi-content.s3.amazonaws.com/wayne/404redirectionScripts/tryAgainEntityScript.js", - "shapeType": "static-mesh", - "type": "Model", + "shapeType": "box", + "skyboxMode": "enabled", + "type": "Zone", "userData": "{\"grabbableKey\":{\"grabbable\":false}}" }, { @@ -485,7 +303,7 @@ "y": 227, "z": 211 }, - "created": "2018-09-04T20:35:23Z", + "created": "2018-09-05T00:40:03Z", "dimensions": { "blue": 2.5, "green": 2.5, @@ -518,8 +336,8 @@ }, "emitRate": 2, "emitSpeed": 0, - "id": "{4b942dd2-dcfa-4959-8758-073c56d6a380}", - "lastEdited": 1536093329670643, + "id": "{639a51f0-8613-4e46-bc7e-fef24597df73}", + "lastEdited": 1536107948776693, "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", "lifespan": 10, "locked": true, @@ -530,16 +348,16 @@ "polarFinish": 3.1415927410125732, "position": { "blue": 1.3553659915924072, - "green": 1.44122314453125, - "red": 2.572803497314453, - "x": 2.572803497314453, - "y": 1.44122314453125, + "green": 1.2890124320983887, + "red": 2.5663273334503174, + "x": 2.5663273334503174, + "y": 1.2890124320983887, "z": 1.3553659915924072 }, "queryAACube": { "scale": 4.330127239227295, - "x": 0.40773987770080566, - "y": -0.7238404750823975, + "x": 0.4012637138366699, + "y": -0.8760511875152588, "z": -0.8096976280212402 }, "radiusFinish": 0.10000000149011612, @@ -557,246 +375,6 @@ "type": "ParticleEffect", "userData": "{\"grabbableKey\":{\"grabbable\":false}}" }, - { - "angularDamping": 0, - "clientOnly": false, - "color": { - "blue": 0, - "green": 0, - "red": 255 - }, - "created": "2018-09-04T20:35:23Z", - "dimensions": { - "blue": 0.20000000298023224, - "green": 0.20000000298023224, - "red": 0.20000000298023224, - "x": 0.20000000298023224, - "y": 0.20000000298023224, - "z": 0.20000000298023224 - }, - "id": "{3b13d766-763a-4d44-99d8-42c7b9d7139e}", - "lastEdited": 1536093329671361, - "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", - "locked": true, - "name": "Particle Rotate", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 3.8216662406921387, - "green": 0, - "red": 1.2409718036651611, - "x": 1.2409718036651611, - "y": 0, - "z": 3.8216662406921387 - }, - "queryAACube": { - "scale": 0.3464101552963257, - "x": 1.0677666664123535, - "y": -0.17320507764816284, - "z": 3.648461103439331 - }, - "rotation": { - "w": 0.6444342136383057, - "x": -0.08220034837722778, - "y": -0.6649118661880493, - "z": 0.3684900999069214 - }, - "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", - "scriptTimestamp": 1532724769253, - "shape": "Cube", - "type": "Box", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}", - "visible": false - }, - { - "alpha": 0, - "alphaFinish": 0, - "alphaStart": 0.25, - "clientOnly": false, - "colorFinish": { - "blue": 0, - "green": 0, - "red": 0, - "x": 0, - "y": 0, - "z": 0 - }, - "colorStart": { - "blue": 255, - "green": 255, - "red": 255, - "x": 255, - "y": 255, - "z": 255 - }, - "created": "2018-09-04T20:35:23Z", - "dimensions": { - "blue": 13.24000072479248, - "green": 13.24000072479248, - "red": 13.24000072479248, - "x": 13.24000072479248, - "y": 13.24000072479248, - "z": 13.24000072479248 - }, - "emitAcceleration": { - "blue": 0, - "green": 0.10000000149011612, - "red": 0, - "x": 0, - "y": 0.10000000149011612, - "z": 0 - }, - "emitDimensions": { - "blue": 1, - "green": 1, - "red": 1, - "x": 1, - "y": 1, - "z": 1 - }, - "emitOrientation": { - "w": 1, - "x": -1.52587890625e-05, - "y": -1.52587890625e-05, - "z": -1.52587890625e-05 - }, - "emitRate": 6, - "emitSpeed": 0, - "emitterShouldTrail": true, - "id": "{e36388d2-7209-4f26-974b-54d314e106a5}", - "lastEdited": 1536093329671654, - "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", - "lifespan": 10, - "locked": true, - "maxParticles": 10, - "name": "Stars", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "particleRadius": 0.07000000029802322, - "polarFinish": 3.1415927410125732, - "position": { - "blue": 3.78922963142395, - "green": 0.5220947265625, - "red": 1.1928560733795166, - "x": 1.1928560733795166, - "y": 0.5220947265625, - "z": 3.78922963142395 - }, - "queryAACube": { - "scale": 22.932353973388672, - "x": -10.273321151733398, - "y": -10.944082260131836, - "z": -7.676947593688965 - }, - "radiusFinish": 0, - "radiusStart": 0, - "rotation": { - "w": 0.996429443359375, - "x": -1.52587890625e-05, - "y": -0.08442819118499756, - "z": -4.57763671875e-05 - }, - "speedSpread": 0, - "spinFinish": null, - "spinStart": null, - "textures": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/star.png", - "type": "ParticleEffect", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}" - }, - { - "angularDamping": 0, - "clientOnly": false, - "color": { - "blue": 0, - "green": 0, - "red": 255 - }, - "created": "2018-09-04T20:35:23Z", - "dimensions": { - "blue": 0.20000000298023224, - "green": 0.20000000298023224, - "red": 0.20000000298023224, - "x": 0.20000000298023224, - "y": 0.20000000298023224, - "z": 0.20000000298023224 - }, - "id": "{1dbde8e2-c715-4c09-814e-e411803278c9}", - "lastEdited": 1536093329670778, - "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", - "locked": true, - "name": "Particle Rotate", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 3.8216662406921387, - "green": 0.0772705078125, - "red": 1.2409718036651611, - "x": 1.2409718036651611, - "y": 0.0772705078125, - "z": 3.8216662406921387 - }, - "queryAACube": { - "scale": 0.3464101552963257, - "x": 1.0677666664123535, - "y": -0.09593456983566284, - "z": 3.648461103439331 - }, - "rotation": { - "w": 0.926024317741394, - "x": 0.20308232307434082, - "y": -0.010269343852996826, - "z": 0.3179827928543091 - }, - "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", - "scriptTimestamp": 1532724769253, - "shape": "Cube", - "type": "Box", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}", - "visible": false - }, - { - "clientOnly": false, - "color": { - "blue": 0, - "green": 0, - "red": 0 - }, - "created": "2018-09-04T20:35:23Z", - "dimensions": { - "blue": 11.117486953735352, - "green": 3.580313205718994, - "red": 0.20000000298023224, - "x": 0.20000000298023224, - "y": 3.580313205718994, - "z": 11.117486953735352 - }, - "id": "{a06f47da-06e5-4bcd-baa2-37816130f2bd}", - "lastEdited": 1536093329671244, - "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", - "locked": true, - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 6.1806135177612305, - "green": 1.1588134765625, - "red": 1.4755167961120605, - "x": 1.4755167961120605, - "y": 1.1588134765625, - "z": 6.1806135177612305 - }, - "queryAACube": { - "scale": 11.681488037109375, - "x": -4.365227222442627, - "y": -4.6819305419921875, - "z": 0.33986949920654297 - }, - "rotation": { - "w": 0.8637980222702026, - "x": -4.57763671875e-05, - "y": 0.5038070678710938, - "z": -1.52587890625e-05 - }, - "shape": "Cube", - "type": "Box", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}", - "visible": false - }, { "alpha": 0, "alphaFinish": 0, @@ -823,7 +401,7 @@ "y": 204, "z": 255 }, - "created": "2018-09-04T20:35:23Z", + "created": "2018-09-05T00:40:03Z", "dimensions": { "blue": 2.5, "green": 2.5, @@ -857,8 +435,8 @@ "emitRate": 2, "emitSpeed": 0, "emitterShouldTrail": true, - "id": "{0b1d2de0-39bf-4416-ac72-aae7ddbb3ff0}", - "lastEdited": 1536093329672220, + "id": "{e62ced49-fa18-4ae1-977f-abef5bc0f3ba}", + "lastEdited": 1536107948775366, "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", "lifespan": 10, "locked": true, @@ -869,16 +447,16 @@ "polarFinish": 3.1415927410125732, "position": { "blue": 3.814434051513672, - "green": 1.44122314453125, - "red": 1.2319090366363525, - "x": 1.2319090366363525, - "y": 1.44122314453125, + "green": 1.2890124320983887, + "red": 1.2254328727722168, + "x": 1.2254328727722168, + "y": 1.2890124320983887, "z": 3.814434051513672 }, "queryAACube": { "scale": 4.330127239227295, - "x": -0.9331545829772949, - "y": -0.7238404750823975, + "x": -0.9396307468414307, + "y": -0.8760511875152588, "z": 1.6493704319000244 }, "radiusFinish": 0.10000000149011612, @@ -896,189 +474,6 @@ "type": "ParticleEffect", "userData": "{\"grabbableKey\":{\"grabbable\":false}}" }, - { - "angularDamping": 0, - "clientOnly": false, - "color": { - "blue": 0, - "green": 0, - "red": 255 - }, - "created": "2018-09-04T20:35:23Z", - "dimensions": { - "blue": 0.20000000298023224, - "green": 0.20000000298023224, - "red": 0.20000000298023224, - "x": 0.20000000298023224, - "y": 0.20000000298023224, - "z": 0.20000000298023224 - }, - "id": "{01d9478b-50ae-4f09-b67a-e62a4d133cdf}", - "lastEdited": 1536093329672981, - "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", - "locked": true, - "name": "Particle Rotate", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 3.8216662406921387, - "green": 0.15618896484375, - "red": 1.2409718036651611, - "x": 1.2409718036651611, - "y": 0.15618896484375, - "z": 3.8216662406921387 - }, - "queryAACube": { - "scale": 0.3464101552963257, - "x": 1.0677666664123535, - "y": -0.017016112804412842, - "z": 3.648461103439331 - }, - "rotation": { - "w": 0.6747081279754639, - "x": -0.06532388925552368, - "y": -0.6342412233352661, - "z": 0.37175559997558594 - }, - "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", - "scriptTimestamp": 1532724769253, - "shape": "Cube", - "type": "Box", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}", - "visible": false - }, - { - "clientOnly": false, - "color": { - "blue": 0, - "green": 0, - "red": 0 - }, - "created": "2018-09-04T20:35:23Z", - "dimensions": { - "blue": 6.9401350021362305, - "green": 0.04553089290857315, - "red": 7.004304885864258, - "x": 7.004304885864258, - "y": 0.04553089290857315, - "z": 6.9401350021362305 - }, - "id": "{718b3532-0c3c-4689-ac41-dca8fedffc4a}", - "lastEdited": 1536093496994604, - "lastEditedBy": "{4eecd88f-ef9b-4a83-bb9a-7f7496209c6b}", - "locked": true, - "name": "floor", - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 3.6175529956817627, - "green": 0.15221074223518372, - "red": 4.108861923217773, - "x": 4.108861923217773, - "y": 0.15221074223518372, - "z": 3.6175529956817627 - }, - "queryAACube": { - "scale": 9.860417366027832, - "x": -0.8213467597961426, - "y": -4.777997970581055, - "z": -1.3126556873321533 - }, - "rotation": { - "w": 0.8660253882408142, - "x": -1.5922749298624694e-05, - "y": 0.5, - "z": -4.572480611386709e-05 - }, - "shape": "Cube", - "type": "Box", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}" - }, - { - "clientOnly": false, - "color": { - "blue": 0, - "green": 0, - "red": 0 - }, - "created": "2018-09-04T20:35:23Z", - "dimensions": { - "blue": 11.117486953735352, - "green": 3.580313205718994, - "red": 0.20000000298023224, - "x": 0.20000000298023224, - "y": 3.580313205718994, - "z": 11.117486953735352 - }, - "id": "{44442e52-e0cf-45d3-9916-678b8aa56a22}", - "lastEdited": 1536093329672691, - "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", - "locked": true, - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 5.268576622009277, - "green": 1.1588134765625, - "red": 6.100250244140625, - "x": 6.100250244140625, - "y": 1.1588134765625, - "z": 5.268576622009277 - }, - "queryAACube": { - "scale": 11.681488037109375, - "x": 0.2595062255859375, - "y": -4.6819305419921875, - "z": -0.5721673965454102 - }, - "rotation": { - "w": 0.9662165641784668, - "x": -4.57763671875e-05, - "y": -0.2576791048049927, - "z": 1.52587890625e-05 - }, - "shape": "Cube", - "type": "Box", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}", - "visible": false - }, - { - "clientOnly": false, - "created": "2018-09-04T20:35:23Z", - "dimensions": { - "blue": 14.40000057220459, - "green": 14.40000057220459, - "red": 14.40000057220459, - "x": 14.40000057220459, - "y": 14.40000057220459, - "z": 14.40000057220459 - }, - "id": "{8a045310-b82f-4021-9963-0b98d317995c}", - "lastEdited": 1536093329670891, - "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", - "locked": true, - "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", - "position": { - "blue": 2.3440732955932617, - "green": 1.7684326171875, - "red": 1.8812973499298096, - "x": 1.8812973499298096, - "y": 1.7684326171875, - "z": 2.3440732955932617 - }, - "queryAACube": { - "scale": 24.9415340423584, - "x": -10.589469909667969, - "y": -10.7023344039917, - "z": -10.126693725585938 - }, - "rotation": { - "w": 0.8697794675827026, - "x": -1.52587890625e-05, - "y": 0.4933699369430542, - "z": -4.57763671875e-05 - }, - "shapeType": "box", - "skyboxMode": "enabled", - "type": "Zone", - "userData": "{\"grabbableKey\":{\"grabbable\":false}}" - }, { "alpha": 0, "alphaFinish": 0, @@ -1100,7 +495,7 @@ "y": 255, "z": 255 }, - "created": "2018-09-04T20:35:23Z", + "created": "2018-09-05T00:40:03Z", "dimensions": { "blue": 13.24000072479248, "green": 13.24000072479248, @@ -1133,8 +528,8 @@ }, "emitRate": 6, "emitSpeed": 0, - "id": "{b310070f-6af8-4c1d-9ad7-ea1070b53763}", - "lastEdited": 1536093329670211, + "id": "{298c0571-cbd8-487b-8640-64037d6a8414}", + "lastEdited": 1536107948776382, "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", "lifespan": 10, "locked": true, @@ -1145,16 +540,16 @@ "polarFinish": 3.1415927410125732, "position": { "blue": 1.3712034225463867, - "green": 0.5220947265625, - "red": 2.6281180381774902, - "x": 2.6281180381774902, - "y": 0.5220947265625, + "green": 0.3698839843273163, + "red": 2.6216418743133545, + "x": 2.6216418743133545, + "y": 0.3698839843273163, "z": 1.3712034225463867 }, "queryAACube": { "scale": 22.932353973388672, - "x": -8.838058471679688, - "y": -10.944082260131836, + "x": -8.844534873962402, + "y": -11.096293449401855, "z": -10.09497356414795 }, "radiusFinish": 0, @@ -1173,56 +568,368 @@ "userData": "{\"grabbableKey\":{\"grabbable\":false}}" }, { - "angularDamping": 0, + "clientOnly": false, + "created": "2018-09-05T00:40:03Z", + "dimensions": { + "blue": 2.1097896099090576, + "green": 0.04847164824604988, + "red": 1.458284616470337, + "x": 1.458284616470337, + "y": 0.04847164824604988, + "z": 2.1097896099090576 + }, + "id": "{6625dbb8-ff25-458d-a92e-644b58460604}", + "lastEdited": 1536107948776195, + "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", + "locked": true, + "modelURL": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/portal1.fbx", + "name": "Try Again", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 3.946338653564453, + "green": 0.09449335932731628, + "red": 1.594836711883545, + "x": 1.594836711883545, + "y": 0.09449335932731628, + "z": 3.946338653564453 + }, + "queryAACube": { + "scale": 2.5651814937591553, + "x": 0.3122459650039673, + "y": -1.188097357749939, + "z": 2.663747787475586 + }, + "rotation": { + "w": 0.8220492601394653, + "x": -1.52587890625e-05, + "y": 0.5693598985671997, + "z": -0.0001068115234375 + }, + "script": "https://hifi-content.s3.amazonaws.com/wayne/404redirectionScripts/tryAgainEntityScript.js", + "shapeType": "static-mesh", + "type": "Model", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}" + }, + { + "clientOnly": false, + "created": "2018-09-05T00:40:03Z", + "dimensions": { + "blue": 0.06014331430196762, + "green": 2.582186460494995, + "red": 2.582186698913574, + "x": 2.582186698913574, + "y": 2.582186460494995, + "z": 0.06014331430196762 + }, + "id": "{dfe92dce-f09d-4e9e-b3ed-c68ecd4d476f}", + "lastEdited": 1536108160862286, + "lastEditedBy": "{4656d4a8-5e61-4230-ab34-2888d7945bd6}", + "locked": true, + "modelURL": "http://hifi-content.s3.amazonaws.com/wayne/models/oopsDialog_protocol.fbx", + "name": "Oops Dialog", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 1.45927095413208, + "green": 1.6763916015625, + "red": 0, + "x": 0, + "y": 1.6763916015625, + "z": 1.45927095413208 + }, + "queryAACube": { + "scale": 3.6522583961486816, + "x": -1.8261291980743408, + "y": -0.14973759651184082, + "z": -0.36685824394226074 + }, + "rotation": { + "w": 0.8684672117233276, + "x": -4.57763671875e-05, + "y": 0.4957197904586792, + "z": -7.62939453125e-05 + }, + "script": "https://hifi-content.s3.amazonaws.com/wayne/404redirectionScripts/oopsEntityScript.js", + "scriptTimestamp": 1536102551825, + "type": "Model", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}" + }, + { "clientOnly": false, "color": { "blue": 0, "green": 0, - "red": 255 + "red": 0 }, - "created": "2018-09-04T20:35:23Z", + "created": "2018-09-05T00:40:03Z", "dimensions": { - "blue": 0.20000000298023224, - "green": 0.20000000298023224, + "blue": 11.117486953735352, + "green": 3.580313205718994, "red": 0.20000000298023224, "x": 0.20000000298023224, - "y": 0.20000000298023224, - "z": 0.20000000298023224 + "y": 3.580313205718994, + "z": 11.117486953735352 }, - "id": "{7c24a30b-47d3-4cf6-af92-5a7959a3cb5d}", - "lastEdited": 1536093329671011, - "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", + "id": "{144a8cf4-b0e8-489a-9403-d74d4dc4cb3e}", + "lastEdited": 1536107948775774, + "lastEditedBy": "{ce82d352-3002-44ae-9b76-66492989a1db}", "locked": true, - "name": "Particle Rotate", + "name": "rightWall", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": { - "blue": 1.3116319179534912, - "green": 0, - "red": 2.705613613128662, - "x": 2.705613613128662, - "y": 0, - "z": 1.3116319179534912 + "blue": 0, + "green": 1.0061144828796387, + "red": 4.965089321136475, + "x": 4.965089321136475, + "y": 1.0061144828796387, + "z": 0 }, "queryAACube": { - "scale": 0.3464101552963257, - "x": 2.5324084758758545, - "y": -0.17320507764816284, - "z": 1.1384267807006836 + "scale": 11.681488037109375, + "x": -0.8756546974182129, + "y": -4.834629535675049, + "z": -5.8407440185546875 }, "rotation": { - "w": 0.9127794504165649, - "x": 0.2575265169143677, - "y": 0.15553522109985352, - "z": 0.2761729955673218 + "w": 0.8637980222702026, + "x": -4.57763671875e-05, + "y": 0.5038070678710938, + "z": -1.52587890625e-05 }, - "script": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/rotate.js", - "scriptTimestamp": 1532724769253, "shape": "Cube", "type": "Box", "userData": "{\"grabbableKey\":{\"grabbable\":false}}", "visible": false + }, + { + "clientOnly": false, + "collidesWith": "static,dynamic,kinematic,otherAvatar,", + "collisionMask": 23, + "created": "2018-09-05T00:40:03Z", + "dimensions": { + "blue": 1.159199833869934, + "green": 2.8062009811401367, + "red": 1.6216505765914917, + "x": 1.6216505765914917, + "y": 2.8062009811401367, + "z": 1.159199833869934 + }, + "id": "{37f53408-3d0c-42a5-9891-e6c40a227349}", + "lastEdited": 1536107948775010, + "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", + "locked": true, + "name": "Back Zone", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 1.8632707595825195, + "green": 1.6500625610351562, + "red": 3.3211965560913086, + "x": 3.3211965560913086, + "y": 1.6500625610351562, + "z": 1.8632707595825195 + }, + "queryAACube": { + "scale": 3.4421300888061523, + "x": 1.6001315116882324, + "y": -0.07100248336791992, + "z": 0.14220571517944336 + }, + "rotation": { + "w": 0.9304176568984985, + "x": 0, + "y": -0.36650121212005615, + "z": 0 + }, + "script": "https://hifi-content.s3.amazonaws.com/wayne/404redirectionScripts/zoneBackEntityScript.js", + "shapeType": "box", + "type": "Zone", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}" + }, + { + "clientOnly": false, + "color": { + "blue": 0, + "green": 0, + "red": 0 + }, + "created": "2018-09-05T00:40:03Z", + "dimensions": { + "blue": 11.117486953735352, + "green": 3.580313205718994, + "red": 0.20000000298023224, + "x": 0.20000000298023224, + "y": 3.580313205718994, + "z": 11.117486953735352 + }, + "id": "{aa6e680c-6750-4776-95bc-ef3118cace5c}", + "lastEdited": 1536107948775945, + "lastEditedBy": "{ce82d352-3002-44ae-9b76-66492989a1db}", + "locked": true, + "name": "frontWall", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 2.662257671356201, + "green": 1.0063786506652832, + "red": 1.4868733882904053, + "x": 1.4868733882904053, + "y": 1.0063786506652832, + "z": 2.662257671356201 + }, + "queryAACube": { + "scale": 11.681488037109375, + "x": -4.353870391845703, + "y": -4.834365367889404, + "z": -3.1784863471984863 + }, + "rotation": { + "w": 0.9666743278503418, + "x": -4.57763671875e-05, + "y": -0.2560006380081177, + "z": 1.52587890625e-05 + }, + "shape": "Cube", + "type": "Box", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}", + "visible": false + }, + { + "clientOnly": false, + "created": "2018-09-05T00:40:03Z", + "dimensions": { + "blue": 2.1097896099090576, + "green": 0.04847164824604988, + "red": 1.458284616470337, + "x": 1.458284616470337, + "y": 0.04847164824604988, + "z": 2.1097896099090576 + }, + "id": "{303631f1-04f3-42a6-b8a8-8dd4b65d1231}", + "lastEdited": 1536107948776513, + "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", + "locked": true, + "modelURL": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/portal2.fbx", + "name": "Back", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "blue": 1.5835940837860107, + "green": 0.09449335932731628, + "red": 3.028078079223633, + "x": 3.028078079223633, + "y": 0.09449335932731628, + "z": 1.5835940837860107 + }, + "queryAACube": { + "scale": 2.5651814937591553, + "x": 1.7454873323440552, + "y": -1.188097357749939, + "z": 0.3010033369064331 + }, + "rotation": { + "w": 0.9084458351135254, + "x": -1.52587890625e-05, + "y": 0.4179598093032837, + "z": -0.0001068115234375 + }, + "script": "https://hifi-content.s3.amazonaws.com/wayne/404redirectionScripts/backEntityScript.js", + "scriptTimestamp": 1535751754379, + "shapeType": "static-mesh", + "type": "Model", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}" + }, + { + "alpha": 0, + "alphaFinish": 0, + "alphaStart": 0.25, + "clientOnly": false, + "colorFinish": { + "blue": 0, + "green": 0, + "red": 0, + "x": 0, + "y": 0, + "z": 0 + }, + "colorStart": { + "blue": 255, + "green": 255, + "red": 255, + "x": 255, + "y": 255, + "z": 255 + }, + "created": "2018-09-05T00:40:03Z", + "dimensions": { + "blue": 13.24000072479248, + "green": 13.24000072479248, + "red": 13.24000072479248, + "x": 13.24000072479248, + "y": 13.24000072479248, + "z": 13.24000072479248 + }, + "emitAcceleration": { + "blue": 0, + "green": 0.10000000149011612, + "red": 0, + "x": 0, + "y": 0.10000000149011612, + "z": 0 + }, + "emitDimensions": { + "blue": 1, + "green": 1, + "red": 1, + "x": 1, + "y": 1, + "z": 1 + }, + "emitOrientation": { + "w": 1, + "x": -1.52587890625e-05, + "y": -1.52587890625e-05, + "z": -1.52587890625e-05 + }, + "emitRate": 6, + "emitSpeed": 0, + "emitterShouldTrail": true, + "id": "{8ded39e6-303c-48f2-be79-81b715cca9f7}", + "lastEdited": 1536107948777127, + "lastEditedBy": "{b5bba536-25e5-4b12-a1be-5c7cd196a06a}", + "lifespan": 10, + "locked": true, + "maxParticles": 10, + "name": "Stars", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "particleRadius": 0.07000000029802322, + "polarFinish": 3.1415927410125732, + "position": { + "blue": 3.78922963142395, + "green": 0.3698839843273163, + "red": 1.1863799095153809, + "x": 1.1863799095153809, + "y": 0.3698839843273163, + "z": 3.78922963142395 + }, + "queryAACube": { + "scale": 22.932353973388672, + "x": -10.279796600341797, + "y": -11.096293449401855, + "z": -7.676947593688965 + }, + "radiusFinish": 0, + "radiusStart": 0, + "rotation": { + "w": 0.996429443359375, + "x": -1.52587890625e-05, + "y": -0.08442819118499756, + "z": -4.57763671875e-05 + }, + "speedSpread": 0, + "spinFinish": null, + "spinStart": null, + "textures": "http://hifi-content.s3.amazonaws.com/alexia/Models/Portal/star.png", + "type": "ParticleEffect", + "userData": "{\"grabbableKey\":{\"grabbable\":false}}" } ], - "Id": "{c9a2e576-13f3-44fa-8d41-a466b33d16c6}", + "Id": "{18abccad-2d57-4176-9d89-24dc424916f5}", "Version": 93 } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e50473bf29..9405915bcf 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1211,6 +1211,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo auto discoverabilityManager = DependencyManager::get(); connect(&locationUpdateTimer, &QTimer::timeout, discoverabilityManager.data(), &DiscoverabilityManager::updateLocation); + connect(&domainHandler, &DomainHandler::domainConnectionErrorChanged, DependencyManager::get().data(), + &AddressManager::setLastDomainConnectionError); connect(&locationUpdateTimer, &QTimer::timeout, DependencyManager::get().data(), &AddressManager::storeCurrentAddress); locationUpdateTimer.start(DATA_SERVER_LOCATION_CHANGE_UPDATE_MSECS); diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 62cd79a609..1b258e14b1 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -343,9 +343,7 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) { _previousAPILookup.clear(); _shareablePlaceName.clear(); - if (lookupUrl.toString() != REDIRECT_HIFI_ADDRESS) { - setDomainInfo(lookupUrl, trigger); - } + setDomainInfo(lookupUrl, trigger); emit lookupResultsFinished(); QString path = DOMAIN_SPAWNING_POINT; diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h index fab2bdd6cb..7226e92451 100644 --- a/libraries/networking/src/AddressManager.h +++ b/libraries/networking/src/AddressManager.h @@ -56,6 +56,8 @@ const QString GET_PLACE = "/api/v1/places/%1"; * Read-only. * @property {boolean} isConnected - true if you're connected to the domain in your current href * metaverse address, otherwise false. + * @property {Window.ConnectionRefusedReason} lastDomainConnectionError - The last error saved from connecting to a domain + * unsuccessfully. * Read-only. * @property {string} pathname - The location and orientation in your current href metaverse address * (e.g., "/15,-10,26/0,0,0,1"). @@ -74,6 +76,7 @@ class AddressManager : public QObject, public Dependency { Q_PROPERTY(QUrl href READ currentShareableAddress) Q_PROPERTY(QString protocol READ getProtocol) Q_PROPERTY(QString hostname READ getHost) + Q_PROPERTY(int lastDomainConnectionError READ getLastDomainConnectionError) Q_PROPERTY(QString pathname READ currentPath) Q_PROPERTY(QString placename READ getPlaceName) Q_PROPERTY(QString domainID READ getDomainID) @@ -141,7 +144,8 @@ public: * * @typedef {number} location.LookupTrigger */ - enum LookupTrigger { + enum LookupTrigger + { UserInput, Back, Forward, @@ -184,6 +188,9 @@ public: QUrl getDomainURL() { return _domainURL; } + int getLastDomainConnectionError() { return _lastDomainConnectionError; } + void setLastDomainConnectionError(int reasonCode) { _lastDomainConnectionError = reasonCode; } + public slots: /**jsdoc * Go to a specified metaverse address. @@ -195,7 +202,7 @@ public slots: * Helps ensure that user's location history is correctly maintained. */ void handleLookupString(const QString& lookupString, bool fromSuggestions = false); - + /**jsdoc * Go to a position and orientation resulting from a lookup for a named path in the domain (set in the domain server's * settings). @@ -208,8 +215,9 @@ public slots: // functions and signals that should be exposed are moved to a scripting interface class. // // we currently expect this to be called from NodeList once handleLookupString has been called with a path - bool goToViewpointForPath(const QString& viewpointString, const QString& pathString) - { return handleViewpoint(viewpointString, false, DomainPathResponse, false, pathString); } + bool goToViewpointForPath(const QString& viewpointString, const QString& pathString) { + return handleViewpoint(viewpointString, false, DomainPathResponse, false, pathString); + } /**jsdoc * Go back to the previous location in your navigation history, if there is one. @@ -230,8 +238,10 @@ public slots: * @param {location.LookupTrigger} trigger=StartupFromSettings - The reason for the function call. Helps ensure that user's * location history is correctly maintained. */ - void goToLocalSandbox(QString path = "", LookupTrigger trigger = LookupTrigger::StartupFromSettings) { handleUrl(SANDBOX_HIFI_ADDRESS + path, trigger); } - + void goToLocalSandbox(QString path = "", LookupTrigger trigger = LookupTrigger::StartupFromSettings) { + handleUrl(SANDBOX_HIFI_ADDRESS + path, trigger); + } + /**jsdoc * Go to the default "welcome" metaverse address. * @function location.goToEntry @@ -362,7 +372,8 @@ signals: * location.locationChangeRequired.connect(onLocationChangeRequired); */ void locationChangeRequired(const glm::vec3& newPosition, - bool hasOrientationChange, const glm::quat& newOrientation, + bool hasOrientationChange, + const glm::quat& newOrientation, bool shouldFaceLocation); /**jsdoc @@ -433,7 +444,7 @@ private slots: void handleShareableNameAPIResponse(QNetworkReply* requestReply); private: - void goToAddressFromObject(const QVariantMap& addressMap, const QNetworkReply* reply); + void goToAddressFromObject(const QVariantMap& addressMap, const QNetworkReply* reply); // Set host and port, and return `true` if it was changed. bool setHost(const QString& host, LookupTrigger trigger, quint16 port = 0); @@ -445,8 +456,11 @@ private: bool handleNetworkAddress(const QString& lookupString, LookupTrigger trigger, bool& hostChanged); void handlePath(const QString& path, LookupTrigger trigger, bool wasPathOnly = false); - bool handleViewpoint(const QString& viewpointString, bool shouldFace, LookupTrigger trigger, - bool definitelyPathOnly = false, const QString& pathString = QString()); + bool handleViewpoint(const QString& viewpointString, + bool shouldFace, + LookupTrigger trigger, + bool definitelyPathOnly = false, + const QString& pathString = QString()); bool handleUsername(const QString& lookupString); bool handleDomainID(const QString& host); @@ -457,6 +471,8 @@ private: QUrl _domainURL; QUrl _lastVisitedURL; + // domain connection error from domain handler. + int _lastDomainConnectionError{ -1 }; QUuid _rootPlaceID; PositionGetter _positionGetter; @@ -473,4 +489,4 @@ private: QUrl _previousAPILookup; }; -#endif // hifi_AddressManager_h +#endif // hifi_AddressManager_h diff --git a/libraries/networking/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp index 0febe1e155..75d670cd3d 100644 --- a/libraries/networking/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -480,6 +480,7 @@ void DomainHandler::processDomainServerConnectionDeniedPacket(QSharedPointer Date: Tue, 4 Sep 2018 18:08:34 -0700 Subject: [PATCH 242/545] Unused variable from merge --- assignment-client/src/avatars/AvatarMixerSlave.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index 7d1ac25469..81ee9c18f8 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -440,7 +440,6 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) auto traitsPacketList = NLPacketList::create(PacketType::BulkAvatarTraits, QByteArray(), true, true); const auto& sortedAvatarVector = sortedAvatars.getSortedVector(); for (const auto& sortedAvatar : sortedAvatarVector) { - const auto& avatarData = sortedAvatar.getAvatar(); const Node* otherNode = sortedAvatar.getNode(); auto lastEncodeForOther = sortedAvatar.getTimestamp(); remainingAvatars--; From 2e17140c07e4ff12f44d56be082d73f9438e96b6 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Tue, 4 Sep 2018 18:24:01 -0700 Subject: [PATCH 243/545] fixing loadServerlessDomain function to be from 404 redirect --- interface/src/Application.cpp | 2 +- interface/src/Application.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b4a8c43be7..91f064dfa2 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3518,7 +3518,7 @@ void Application::setIsServerlessMode(bool serverlessDomain) { void Application::loadServerlessDomain(QUrl domainURL, bool errorDomain) { if (QThread::currentThread() != thread()) { - QMetaObject::invokeMethod(this, "loadServerlessDomain", Q_ARG(QUrl, domainURL)); + QMetaObject::invokeMethod(this, "loadServerlessDomain", Q_ARG(QUrl, domainURL), Q_ARG(bool, errorDomain)); return; } diff --git a/interface/src/Application.h b/interface/src/Application.h index 35f998a04d..c82dae3b05 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -436,7 +436,6 @@ public slots: void setIsServerlessMode(bool serverlessDomain); void loadServerlessDomain(QUrl domainURL, bool errorDomain = false); void setIsInterstitialMode(bool interstialMode); - void loadServerlessDomain(QUrl domainURL); void updateVerboseLogging(); From 1ce6c84c089e55c9c3f8118cb4b760ef4cadfbda Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Tue, 4 Sep 2018 18:24:49 -0700 Subject: [PATCH 244/545] updating metacall for loadServerlessDomain --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9405915bcf..1104e153df 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3479,7 +3479,7 @@ void Application::setIsServerlessMode(bool serverlessDomain) { void Application::loadServerlessDomain(QUrl domainURL, bool errorDomain) { if (QThread::currentThread() != thread()) { - QMetaObject::invokeMethod(this, "loadServerlessDomain", Q_ARG(QUrl, domainURL)); + QMetaObject::invokeMethod(this, "loadServerlessDomain", Q_ARG(QUrl, domainURL), Q_ARG(bool, errorDomain)); return; } From 98c4d05b4ada1a76c469363769e9078054fea8ed Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Tue, 4 Sep 2018 19:54:30 -0700 Subject: [PATCH 245/545] fixing typo in domain handler --- libraries/networking/src/DomainHandler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/DomainHandler.h b/libraries/networking/src/DomainHandler.h index 2784605961..5e9d0f14e9 100644 --- a/libraries/networking/src/DomainHandler.h +++ b/libraries/networking/src/DomainHandler.h @@ -84,7 +84,7 @@ public: void connectedToServerless(std::map namedPaths); - void DomainHandler::loadedErrorDomain(std::map namedPaths); + void loadedErrorDomain(std::map namedPaths); QString getViewPointFromNamedPath(QString namedPath); From 0be7a5ffaa92949954a0c5a2148eb9eb573bfdfd Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Tue, 4 Sep 2018 19:58:56 -0700 Subject: [PATCH 246/545] fixing typo in domain handler --- libraries/networking/src/DomainHandler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/DomainHandler.h b/libraries/networking/src/DomainHandler.h index 2784605961..5e9d0f14e9 100644 --- a/libraries/networking/src/DomainHandler.h +++ b/libraries/networking/src/DomainHandler.h @@ -84,7 +84,7 @@ public: void connectedToServerless(std::map namedPaths); - void DomainHandler::loadedErrorDomain(std::map namedPaths); + void loadedErrorDomain(std::map namedPaths); QString getViewPointFromNamedPath(QString namedPath); From af1c473a9c62ae0039f4705d2bbfb8b3d2f754b7 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Tue, 4 Sep 2018 22:17:33 -0700 Subject: [PATCH 247/545] updating with models in meshes folder --- .../meshes/redirect/oopsDialog_auth.fbx | Bin 0 -> 32304 bytes .../meshes/redirect/oopsDialog_auth.png | Bin 0 -> 5012 bytes .../meshes/redirect/oopsDialog_protocol.fbx | Bin 0 -> 32256 bytes .../meshes/redirect/oopsDialog_protocol.png | Bin 0 -> 4899 bytes .../meshes/redirect/oopsDialog_vague.fbx | Bin 0 -> 32480 bytes .../meshes/redirect/oopsDialog_vague.png | Bin 0 -> 5139 bytes interface/resources/serverless/redirect.json | 4 +- scripts/system/oopsEntityScript.js | 41 ++++++++++++++++++ 8 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 interface/resources/meshes/redirect/oopsDialog_auth.fbx create mode 100644 interface/resources/meshes/redirect/oopsDialog_auth.png create mode 100644 interface/resources/meshes/redirect/oopsDialog_protocol.fbx create mode 100644 interface/resources/meshes/redirect/oopsDialog_protocol.png create mode 100644 interface/resources/meshes/redirect/oopsDialog_vague.fbx create mode 100644 interface/resources/meshes/redirect/oopsDialog_vague.png create mode 100644 scripts/system/oopsEntityScript.js diff --git a/interface/resources/meshes/redirect/oopsDialog_auth.fbx b/interface/resources/meshes/redirect/oopsDialog_auth.fbx new file mode 100644 index 0000000000000000000000000000000000000000..3360de993f31b3b2ba600056ed9cd08365c7a473 GIT binary patch literal 32304 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 literal 0 HcmV?d00001 diff --git a/interface/resources/meshes/redirect/oopsDialog_protocol.png b/interface/resources/meshes/redirect/oopsDialog_protocol.png new file mode 100644 index 0000000000000000000000000000000000000000..63c6e00c4eaa31798af10e5d5f9165290628bc0f GIT binary patch literal 4899 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 literal 0 HcmV?d00001 diff --git a/interface/resources/meshes/redirect/oopsDialog_vague.fbx b/interface/resources/meshes/redirect/oopsDialog_vague.fbx new file mode 100644 index 0000000000000000000000000000000000000000..324d90578b833552f01a1199fbded078b49900ba GIT binary patch literal 32480 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 G%l`rndU6E- literal 0 HcmV?d00001 diff --git a/interface/resources/meshes/redirect/oopsDialog_vague.png b/interface/resources/meshes/redirect/oopsDialog_vague.png new file mode 100644 index 0000000000000000000000000000000000000000..8a02ad2c277d5b218b45d96429b48c02f636b50d GIT binary patch literal 5139 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 Mv$| 0) { + this.entityID = entities[0]; + } + } + var error = location.lastDomainConnectionError; + var newModel = ""; + var hostedSite = Script.resourcesPath() + "meshes/redirect"; + if (error === PROTOCOL_MISMATCH) { + newModel = "oopsDialog_protocol"; + } else if (error === NOT_AUTHORIZED) { + newModel = "oopsDialog_auth"; + } else { + newModel = "oopsDialog_vague"; + } + var props = Entities.getEntityProperties(this.entityID, ["modelURL"]); + var newModelURL = hostedSite + newModel + ".fbx"; + if(props.modelURL !== newModelURL) { + var newFileURL = newModelURL + "/" + newModel + ".png"; + var newTextures = {"file16": newFileURL, "file17": newFileURL}; + Entities.editEntity(this.entityID, {modelURL: newModelURL, originalTextures: JSON.stringify(newTextures)}); + } + }; + var ping = Script.setInterval(pingError, 5000); + + function cleanup() { + Script.clearInterval(ping); + }; + + Script.scriptEnding.connect(cleanup); +}); From 8b6c21e0bbd94f4e0b1ed66aca3188aee8d58d23 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Tue, 4 Sep 2018 22:19:12 -0700 Subject: [PATCH 248/545] updating script path TODO: will fix with s3 hosted script --- interface/resources/serverless/redirect.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/serverless/redirect.json b/interface/resources/serverless/redirect.json index ec172561af..00bbe17691 100644 --- a/interface/resources/serverless/redirect.json +++ b/interface/resources/serverless/redirect.json @@ -648,7 +648,7 @@ "y": 0.4957197904586792, "z": -7.62939453125e-05 }, - "script": "https://raw.githubusercontent.com/wayne-chen/hifi/404DomainRedirect/scripts/system/oopsEntityScript.js", + "script": "https://raw.githubusercontent.com/wayne-chen/hifi/interstitalMerged/scripts/system/oopsEntityScript.js", "scriptTimestamp": 1536102551825, "type": "Model", "userData": "{\"grabbableKey\":{\"grabbable\":false}}" From afd7321e7f81a19f48b797887849cc7ebb7e9612 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Tue, 4 Sep 2018 23:16:54 -0700 Subject: [PATCH 249/545] updating redirect with proper fbx TODO: fix path when uploaded the fbx files --- interface/resources/serverless/redirect.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/serverless/redirect.json b/interface/resources/serverless/redirect.json index ec172561af..17799b952d 100644 --- a/interface/resources/serverless/redirect.json +++ b/interface/resources/serverless/redirect.json @@ -625,7 +625,7 @@ "lastEdited": 1536108160862286, "lastEditedBy": "{4656d4a8-5e61-4230-ab34-2888d7945bd6}", "locked": true, - "modelURL": Script.resourcesPath() + "meshes/redirect/oopsDialog_protocol.fbx", + "modelURL": "https://raw.githubusercontent.com/wayne-chen/hifi/404DomainRedirect/interface/resources/meshes/redirect/oopsDialog_protocol.fbx", "name": "Oops Dialog", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": { From d6442b350c4da1110db0111a6d3283b593f5cc80 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Tue, 4 Sep 2018 23:18:52 -0700 Subject: [PATCH 250/545] updating redirect to the interstitial page url TODO: Fix this link to s3 bucket hosted file --- interface/resources/serverless/redirect.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/serverless/redirect.json b/interface/resources/serverless/redirect.json index 511c1c410c..539e92203b 100644 --- a/interface/resources/serverless/redirect.json +++ b/interface/resources/serverless/redirect.json @@ -625,7 +625,7 @@ "lastEdited": 1536108160862286, "lastEditedBy": "{4656d4a8-5e61-4230-ab34-2888d7945bd6}", "locked": true, - "modelURL": "https://raw.githubusercontent.com/wayne-chen/hifi/404DomainRedirect/interface/resources/meshes/redirect/oopsDialog_protocol.fbx", + "modelURL": "https://raw.githubusercontent.com/wayne-chen/hifi/interstitalMerged/interface/resources/meshes/redirect/oopsDialog_protocol.fbx", "name": "Oops Dialog", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": { From f38a26a1ffd0e95aeffa229ae4fc9a08be98cfbe Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Wed, 5 Sep 2018 09:04:17 -0700 Subject: [PATCH 251/545] updating location of oops dialog script --- interface/resources/serverless/redirect.json | 4 +- scripts/system/oopsEntityScript.js | 41 -------------------- 2 files changed, 2 insertions(+), 43 deletions(-) delete mode 100644 scripts/system/oopsEntityScript.js diff --git a/interface/resources/serverless/redirect.json b/interface/resources/serverless/redirect.json index 17799b952d..1bb2aa80c7 100644 --- a/interface/resources/serverless/redirect.json +++ b/interface/resources/serverless/redirect.json @@ -625,7 +625,7 @@ "lastEdited": 1536108160862286, "lastEditedBy": "{4656d4a8-5e61-4230-ab34-2888d7945bd6}", "locked": true, - "modelURL": "https://raw.githubusercontent.com/wayne-chen/hifi/404DomainRedirect/interface/resources/meshes/redirect/oopsDialog_protocol.fbx", + "modelURL": "", "name": "Oops Dialog", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": { @@ -648,7 +648,7 @@ "y": 0.4957197904586792, "z": -7.62939453125e-05 }, - "script": "https://raw.githubusercontent.com/wayne-chen/hifi/404DomainRedirect/scripts/system/oopsEntityScript.js", + "script": "https://hifi-content.s3.amazonaws.com/wayne/404redirectionScripts/oopsEntityScript.js", "scriptTimestamp": 1536102551825, "type": "Model", "userData": "{\"grabbableKey\":{\"grabbable\":false}}" diff --git a/scripts/system/oopsEntityScript.js b/scripts/system/oopsEntityScript.js deleted file mode 100644 index bf10fbb9dd..0000000000 --- a/scripts/system/oopsEntityScript.js +++ /dev/null @@ -1,41 +0,0 @@ -(function() { - var PROTOCOL_MISMATCH = 1; - var NOT_AUTHORIZED = 3; - - this.entityID = Uuid.NULL; - this.preload = function(entityID) { - this.entityID = entityID; - }; - function pingError() { - if(this.entityID === undefined) { - var entities = Entities.findEntitiesByName("Oops Dialog", MyAvatar.position, 10); - if(entities.length > 0) { - this.entityID = entities[0]; - } - } - var error = location.lastDomainConnectionError; - var newModel = ""; - var hostedSite = Script.resourcesPath() + "meshes/redirect"; - if (error === PROTOCOL_MISMATCH) { - newModel = "oopsDialog_protocol"; - } else if (error === NOT_AUTHORIZED) { - newModel = "oopsDialog_auth"; - } else { - newModel = "oopsDialog_vague"; - } - var props = Entities.getEntityProperties(this.entityID, ["modelURL"]); - var newModelURL = hostedSite + newModel + ".fbx"; - if(props.modelURL !== newModelURL) { - var newFileURL = newModelURL + "/" + newModel + ".png"; - var newTextures = {"file16": newFileURL, "file17": newFileURL}; - Entities.editEntity(this.entityID, {modelURL: newModelURL, originalTextures: JSON.stringify(newTextures)}); - } - }; - var ping = Script.setInterval(pingError, 5000); - - function cleanup() { - Script.clearInterval(ping); - }; - - Script.scriptEnding.connect(cleanup); -}); From 179138aa106895efafdf6a26469a31061946a9a8 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Wed, 5 Sep 2018 10:36:06 -0700 Subject: [PATCH 252/545] updating serverless file to have dynamic oops --- interface/resources/serverless/redirect.json | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/resources/serverless/redirect.json b/interface/resources/serverless/redirect.json index 1bb2aa80c7..48b1a7078f 100644 --- a/interface/resources/serverless/redirect.json +++ b/interface/resources/serverless/redirect.json @@ -624,7 +624,6 @@ "id": "{dfe92dce-f09d-4e9e-b3ed-c68ecd4d476f}", "lastEdited": 1536108160862286, "lastEditedBy": "{4656d4a8-5e61-4230-ab34-2888d7945bd6}", - "locked": true, "modelURL": "", "name": "Oops Dialog", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", From c6229c5c604731e3154d31455e5f5fe46b6242ff Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Wed, 5 Sep 2018 10:37:45 -0700 Subject: [PATCH 253/545] updating serverless file to have dynamic oops --- interface/resources/serverless/redirect.json | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/resources/serverless/redirect.json b/interface/resources/serverless/redirect.json index 1bb2aa80c7..48b1a7078f 100644 --- a/interface/resources/serverless/redirect.json +++ b/interface/resources/serverless/redirect.json @@ -624,7 +624,6 @@ "id": "{dfe92dce-f09d-4e9e-b3ed-c68ecd4d476f}", "lastEdited": 1536108160862286, "lastEditedBy": "{4656d4a8-5e61-4230-ab34-2888d7945bd6}", - "locked": true, "modelURL": "", "name": "Oops Dialog", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", From 1bea6c9ea38f223d730f409542bb965d43858b93 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 5 Sep 2018 10:38:12 -0700 Subject: [PATCH 254/545] if not already logged in, show login dialog at launch-time rather than connect-to-domain-time --- interface/src/Application.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 67dbcf355f..a2f5033622 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2299,6 +2299,19 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo connect(&AndroidHelper::instance(), &AndroidHelper::enterForeground, this, &Application::enterForeground); AndroidHelper::instance().notifyLoadComplete(); #endif + + static int CHECK_LOGIN_TIMER = 3000; + QTimer* checkLoginTimer = new QTimer(this); + checkLoginTimer->setInterval(CHECK_LOGIN_TIMER); + checkLoginTimer->setSingleShot(true); + connect(checkLoginTimer, &QTimer::timeout, this, []() { + auto accountManager = DependencyManager::get(); + auto dialogsManager = DependencyManager::get(); + if (!accountManager->isLoggedIn()) { + dialogsManager->showLoginDialog(); + } + }); + checkLoginTimer->start(); } void Application::updateVerboseLogging() { From f7e84995b41961d08ac6ecdcffef170c8b6c3253 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 5 Sep 2018 10:58:37 -0700 Subject: [PATCH 255/545] Only build the sortable vector once, now we're using vectors for the priority sort --- .../src/avatars/AvatarMixerSlave.cpp | 60 ++++++------------- 1 file changed, 18 insertions(+), 42 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index 81ee9c18f8..a61f65ffb0 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -288,35 +288,6 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // Quadruple the scale of first bounding box nodeBox.embiggen(4.0f); - - // setup list of AvatarData as well as maps to map betweeen the AvatarData and the original nodes - struct AvatarSortData { - AvatarSortData(const Node* node, AvatarData* avatarData, quint64 lastEncodeTime) - : _node(node) - , _avatarData(avatarData) - , _lastEncodeTime(lastEncodeTime) - { } - const Node* _node; - AvatarData* _avatarData; - quint64 _lastEncodeTime; - }; - // Temporary info about the avatars we're sending: - std::vector avatarsToSort; - avatarsToSort.reserve(_end - _begin); - std::for_each(_begin, _end, [&](const SharedNodePointer& otherNode) { - Node* otherNodeRaw = otherNode.data(); - // make sure this is an agent that we have avatar data for before considering it for inclusion - if (otherNodeRaw->getType() == NodeType::Agent - && otherNodeRaw->getLinkedData()) { - const AvatarMixerClientData* otherNodeData = reinterpret_cast(otherNodeRaw->getLinkedData()); - - - AvatarData* otherAvatar = otherNodeData->getAvatarSharedPointer().get(); - auto lastEncodeTime = nodeData->getLastOtherAvatarEncodeTime(otherAvatar->getSessionUUID()); - avatarsToSort.emplace_back(AvatarSortData(otherNodeRaw, otherAvatar, lastEncodeTime)); - } - }); - class SortableAvatar: public PrioritySortUtil::Sortable { public: SortableAvatar() = delete; @@ -345,16 +316,18 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) AvatarData::_avatarSortCoefficientSize, AvatarData::_avatarSortCoefficientCenter, AvatarData::_avatarSortCoefficientAge); - sortedAvatars.reserve(avatarsToSort.size()); + sortedAvatars.reserve(_end - _begin); - // ignore or sort - for (const auto& avatar : avatarsToSort) { - auto avatarNode = avatar._node; - if (avatarNode == destinationNode) { - // don't echo updates to self + for (auto listedNode = _begin; listedNode != _end; ++listedNode) { + Node* otherNodeRaw = (*listedNode).data(); + if (otherNodeRaw->getType() != NodeType::Agent + || !otherNodeRaw->getLinkedData() + || otherNodeRaw == destinationNode) { continue; } + auto avatarNode = otherNodeRaw; + bool shouldIgnore = false; // We ignore other nodes for a couple of reasons: // 1) ignore bubbles and ignore specific node @@ -364,8 +337,8 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) assert(avatarNode); // we can't have gotten here without the avatarData being a valid key in the map - const AvatarMixerClientData* avatarNodeData = reinterpret_cast(avatarNode->getLinkedData()); - assert(avatarNodeData); // we can't have gotten here without avatarNode having valid data + const AvatarMixerClientData* avatarClientNodeData = reinterpret_cast(avatarNode->getLinkedData()); + assert(avatarClientNodeData); // we can't have gotten here without avatarNode having valid data quint64 startIgnoreCalculation = usecTimestampNow(); // make sure we have data for this avatar, that it isn't the same node, @@ -378,11 +351,11 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // Check to see if the space bubble is enabled // Don't bother with these checks if the other avatar has their bubble enabled and we're gettingAnyIgnored if (destinationNode->isIgnoreRadiusEnabled() || (avatarNode->isIgnoreRadiusEnabled() && !getsAnyIgnored)) { - float sensorToWorldScale = avatarNodeData->getAvatarSharedPointer()->getSensorToWorldScale(); + float sensorToWorldScale = avatarClientNodeData->getAvatarSharedPointer()->getSensorToWorldScale(); // Define the scale of the box for the current other node - glm::vec3 otherNodeBoxScale = (avatarNodeData->getPosition() - avatarNodeData->getGlobalBoundingBoxCorner()) * 2.0f * sensorToWorldScale; + glm::vec3 otherNodeBoxScale = (avatarClientNodeData->getPosition() - avatarClientNodeData->getGlobalBoundingBoxCorner()) * 2.0f * sensorToWorldScale; // Set up the bounding box for the current other node - AABox otherNodeBox(avatarNodeData->getGlobalBoundingBoxCorner(), otherNodeBoxScale); + AABox otherNodeBox(avatarClientNodeData->getGlobalBoundingBoxCorner(), otherNodeBoxScale); // Clamp the size of the bounding box to a minimum scale if (glm::any(glm::lessThan(otherNodeBoxScale, minBubbleSize))) { otherNodeBox.setScaleStayCentered(minBubbleSize); @@ -405,7 +378,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) if (!shouldIgnore) { AvatarDataSequenceNumber lastSeqToReceiver = nodeData->getLastBroadcastSequenceNumber(avatarNode->getUUID()); - AvatarDataSequenceNumber lastSeqFromSender = avatarNodeData->getLastReceivedSequenceNumber(); + AvatarDataSequenceNumber lastSeqFromSender = avatarClientNodeData->getLastReceivedSequenceNumber(); // FIXME - This code does appear to be working. But it seems brittle. // It supports determining if the frame of data for this "other" @@ -430,7 +403,10 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) if (!shouldIgnore) { // sort this one for later - sortedAvatars.push(SortableAvatar(avatar._avatarData, avatar._node, avatar._lastEncodeTime)); + const AvatarData* avatarNodeData = avatarClientNodeData->getConstAvatarData(); + auto lastEncodeTime = nodeData->getLastOtherAvatarEncodeTime(avatarNodeData->getSessionUUID()); + + sortedAvatars.push(SortableAvatar(avatarNodeData, avatarNode, lastEncodeTime)); } } From 8344cb9affebbf01e4da273817d00c64869a4b83 Mon Sep 17 00:00:00 2001 From: sam gateau Date: Wed, 5 Sep 2018 11:07:04 -0700 Subject: [PATCH 256/545] REfactor the FBXReader_Mesh for different vertex formats --- libraries/fbx/src/FBXReader_Mesh.cpp | 154 ++++++++++++++++++--------- 1 file changed, 104 insertions(+), 50 deletions(-) diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index 4ecca2b234..ce80dfb592 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -745,66 +745,116 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { // Now we decide on how to interleave the attributes and provide the vertices among bufers: - // Aka the Vertex format - auto vf = std::make_shared(); - gpu::Offset buf0Offset = 0; - vf->setAttribute(gpu::Stream::POSITION, 0, positionElement); - buf0Offset += positionElement.getSize(); + // Aka the Vertex format and the vertexBufferStream + auto vertexFormat = std::make_shared(); + auto vertexBufferStream = std::make_shared(); - gpu::Offset buf1Offset = 0; - if (normalsSize) { - vf->setAttribute(gpu::Stream::NORMAL, 1, normalElement, buf1Offset); - buf1Offset = normalElement.getSize(); - vf->setAttribute(gpu::Stream::TANGENT, 1, normalElement, buf1Offset); - buf1Offset = normalElement.getSize(); + // Decision time: + // if blendshapes then keep position and normals/tangents as separated channel buffers from interleaved attributes + // else everything is interleaved in one buffer + + // Default case is no blend shapes + gpu::BufferPointer attribBuffer; + int totalAttribBufferSize = totalVertsSize; + gpu::uint8 posChannel = 0; + gpu::uint8 tangentChannel = posChannel; + gpu::uint8 attribChannel = posChannel; + bool interleavePositions = true; + bool interleaveNormalsTangents = true; + + // If has blend shapes allocate and assign buffers for pos and tangents now + if (hasBlendShapes) { + + auto posBuffer = std::make_shared(); + posBuffer->setData(positionsSize, (const gpu::Byte*) vertBuffer->getData() + positionsOffset); + vertexBufferStream->addBuffer(posBuffer, 0, positionElement.getSize()); + + auto tangentBuffer = std::make_shared(); + tangentBuffer->setData(normalsAndTangentsSize, (const gpu::Byte*) vertBuffer->getData() + normalsAndTangentsOffset); + vertexBufferStream->addBuffer(tangentBuffer, 0, normalsAndTangentsStride); + + // update channels and attribBuffer size accordingly + interleavePositions = false; + interleaveNormalsTangents = false; + + tangentChannel = 1; + attribChannel = 2; + + totalAttribBufferSize = totalVertsSize - positionsSize - normalsAndTangentsSize; + } else { +/* + auto posBuffer = std::make_shared(); + posBuffer->setData(positionsSize, (const gpu::Byte*) vertBuffer->getData() + positionsOffset); + vertexBufferStream->addBuffer(posBuffer, 0, positionElement.getSize()); + + // update channels and attribBuffer size accordingly + interleavePositions = false; + + auto tangentBuffer = std::make_shared(); + tangentBuffer->setData(normalsAndTangentsSize, (const gpu::Byte*) vertBuffer->getData() + normalsAndTangentsOffset); + vertexBufferStream->addBuffer(tangentBuffer, 0, normalsAndTangentsStride); + + interleaveNormalsTangents = false; + + tangentChannel = 1; + attribChannel = 2; + + totalAttribBufferSize = totalVertsSize - positionsSize - normalsAndTangentsSize;*/ } - gpu::Offset buf2Offset = (0); + // Define the vertex format, compute the offset for each attributes as we append them to the vertex format + gpu::Offset bufOffset = 0; + if (positionsSize) { + vertexFormat->setAttribute(gpu::Stream::POSITION, posChannel, positionElement, bufOffset); + bufOffset += positionElement.getSize(); + if (!interleavePositions) { + bufOffset = 0; + } + } + if (normalsSize) { + vertexFormat->setAttribute(gpu::Stream::NORMAL, tangentChannel, normalElement, bufOffset); + bufOffset = normalElement.getSize(); + vertexFormat->setAttribute(gpu::Stream::TANGENT, tangentChannel, normalElement, bufOffset); + bufOffset = normalElement.getSize(); + if (!interleaveNormalsTangents) { + bufOffset = 0; + } + } + + // Pack normal and Tangent with the rest of atributes if no blend shapes if (colorsSize) { - vf->setAttribute(gpu::Stream::COLOR, 2, colorElement, buf2Offset); - buf2Offset += colorElement.getSize(); + vertexFormat->setAttribute(gpu::Stream::COLOR, attribChannel, colorElement, bufOffset); + bufOffset += colorElement.getSize(); } if (texCoordsSize) { - vf->setAttribute(gpu::Stream::TEXCOORD, 2, texCoordsElement, buf2Offset); - buf2Offset += texCoordsElement.getSize(); + vertexFormat->setAttribute(gpu::Stream::TEXCOORD, attribChannel, texCoordsElement, bufOffset); + bufOffset += texCoordsElement.getSize(); } if (texCoords1Size) { - vf->setAttribute(gpu::Stream::TEXCOORD1, 2, texCoordsElement, buf2Offset); - buf2Offset += texCoordsElement.getSize(); + vertexFormat->setAttribute(gpu::Stream::TEXCOORD1, attribChannel, texCoordsElement, bufOffset); + bufOffset += texCoordsElement.getSize(); } else if (texCoordsSize) { - vf->setAttribute(gpu::Stream::TEXCOORD1, 2, texCoordsElement, buf2Offset - texCoordsElement.getSize()); + vertexFormat->setAttribute(gpu::Stream::TEXCOORD1, attribChannel, texCoordsElement, bufOffset - texCoordsElement.getSize()); } if (clusterIndicesSize) { - vf->setAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, 2, clusterIndiceElement, buf2Offset); - buf2Offset += clusterIndiceElement.getSize(); + vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, attribChannel, clusterIndiceElement, bufOffset); + bufOffset += clusterIndiceElement.getSize(); } if (clusterWeightsSize) { - vf->setAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, 2, clusterWeightElement, buf2Offset); - buf2Offset += clusterWeightElement.getSize(); + vertexFormat->setAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, attribChannel, clusterWeightElement, bufOffset); + bufOffset += clusterWeightElement.getSize(); } - auto vbs = std::make_shared(); - - - auto vb = std::make_shared(); - vb->setData(extractedMesh.vertices.size() * sizeof(glm::vec3), - (const gpu::Byte*) extractedMesh.vertices.data()); - gpu::BufferView vbv(vb, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ)); - vbs->addBuffer(vb, 0, buf0Offset); - - auto attribNTBuffer = std::make_shared(); - attribNTBuffer->resize(totalNTSize); - - auto attribBuffer = std::make_shared(); - attribBuffer->resize(totalAttributeSize); - - - + // Finally, allocate and fill the attribBuffer interleaving the attributes as needed: { - vbs->addBuffer(attribNTBuffer, 0, buf1Offset); + auto vPositionOffset = 0; + auto vPositionSize = (interleavePositions ? positionsSize / numVerts : 0); - auto vColorOffset = 0; + auto vNormalsAndTangentsOffset = vPositionOffset + vPositionSize; + auto vNormalsAndTangentsSize = (interleaveNormalsTangents ? normalsAndTangentsSize / numVerts : 0); + + auto vColorOffset = vNormalsAndTangentsOffset + vNormalsAndTangentsSize; auto vColorSize = colorsSize / numVerts; auto vTexcoord0Offset = vColorOffset + vColorSize; @@ -820,16 +870,17 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { auto vClusterWeightSize = clusterWeightsSize / numVerts; auto vStride = vClusterWeightOffset + vClusterWeightSize; - //int vStride = buf2Offset; + std::vector dest; - dest.resize(totalAttributeSize); + dest.resize(totalAttribBufferSize); auto vDest = dest.data(); - auto source = attribBuffer->getData(); - + auto source = vertBuffer->getData(); for (int i = 0; i < numVerts; i++) { + if (vPositionSize) memcpy(vDest + vPositionOffset, source + positionsOffset + i * vPositionSize, vPositionSize); + if (vNormalsAndTangentsSize) memcpy(vDest + vNormalsAndTangentsOffset, source + normalsAndTangentsOffset + i * vNormalsAndTangentsSize, vNormalsAndTangentsSize); if (vColorSize) memcpy(vDest + vColorOffset, source + colorsOffset + i * vColorSize, vColorSize); if (vTexcoord0Size) memcpy(vDest + vTexcoord0Offset, source + texCoordsOffset + i * vTexcoord0Size, vTexcoord0Size); if (vTexcoord1Size) memcpy(vDest + vTexcoord1Offset, source + texCoords1Offset + i * vTexcoord1Size, vTexcoord1Size); @@ -839,12 +890,15 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { vDest += vStride; } - attribBuffer->setData(totalAttributeSize, dest.data()); - - vbs->addBuffer(attribBuffer, 0, vStride); + auto attribBuffer = std::make_shared(); + attribBuffer->setData(totalAttribBufferSize, dest.data()); + vertexBufferStream->addBuffer(attribBuffer, 0, vStride); } - mesh->setVertexFormatAndStream(vf, vbs); + // MEsh vertex format and vertex stream is ready + mesh->setVertexFormatAndStream(vertexFormat, vertexBufferStream); + + // Index and Part Buffers unsigned int totalIndices = 0; foreach(const FBXMeshPart& part, extractedMesh.parts) { totalIndices += (part.quadTrianglesIndices.size() + part.triangleIndices.size()); From 198ec294acd8ee96596a833f64388db7535e5779 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 5 Sep 2018 20:13:48 +0200 Subject: [PATCH 257/545] restore window parent on presentationMode switch --- libraries/ui/src/InteractiveWindow.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/ui/src/InteractiveWindow.cpp b/libraries/ui/src/InteractiveWindow.cpp index b4d5a068eb..6c7f2d503f 100644 --- a/libraries/ui/src/InteractiveWindow.cpp +++ b/libraries/ui/src/InteractiveWindow.cpp @@ -97,6 +97,7 @@ InteractiveWindow::InteractiveWindow(const QString& sourceUrl, const QVariantMap #ifdef Q_OS_WIN connect(object, SIGNAL(nativeWindowChanged()), this, SLOT(parentNativeWindowToMainWindow()), Qt::QueuedConnection); connect(object, SIGNAL(interactiveWindowVisibleChanged()), this, SLOT(parentNativeWindowToMainWindow()), Qt::QueuedConnection); + connect(object, SIGNAL(presentationModeChanged()), this, SLOT(parentNativeWindowToMainWindow()), Qt::QueuedConnection); #endif QUrl sourceURL{ sourceUrl }; From ce86e94e6f7b8c41fe5623d69b68eb1b66ed73ed Mon Sep 17 00:00:00 2001 From: sam gateau Date: Wed, 5 Sep 2018 11:34:33 -0700 Subject: [PATCH 258/545] Add simple optim and instrumentation for tthe number of input buffer changes per frame" --- libraries/fbx/src/FBXReader_Mesh.cpp | 25 +++---------------- .../src/gpu/gl/GLBackendInput.cpp | 9 +++++++ .../gpu-gl/src/gpu/gl41/GL41BackendInput.cpp | 5 +++- .../gpu-gl/src/gpu/gl45/GL45BackendInput.cpp | 15 ++++++----- 4 files changed, 25 insertions(+), 29 deletions(-) diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index ce80dfb592..ef2fcc23b4 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -781,25 +781,6 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { attribChannel = 2; totalAttribBufferSize = totalVertsSize - positionsSize - normalsAndTangentsSize; - } else { -/* - auto posBuffer = std::make_shared(); - posBuffer->setData(positionsSize, (const gpu::Byte*) vertBuffer->getData() + positionsOffset); - vertexBufferStream->addBuffer(posBuffer, 0, positionElement.getSize()); - - // update channels and attribBuffer size accordingly - interleavePositions = false; - - auto tangentBuffer = std::make_shared(); - tangentBuffer->setData(normalsAndTangentsSize, (const gpu::Byte*) vertBuffer->getData() + normalsAndTangentsOffset); - vertexBufferStream->addBuffer(tangentBuffer, 0, normalsAndTangentsStride); - - interleaveNormalsTangents = false; - - tangentChannel = 1; - attribChannel = 2; - - totalAttribBufferSize = totalVertsSize - positionsSize - normalsAndTangentsSize;*/ } // Define the vertex format, compute the offset for each attributes as we append them to the vertex format @@ -813,9 +794,9 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { } if (normalsSize) { vertexFormat->setAttribute(gpu::Stream::NORMAL, tangentChannel, normalElement, bufOffset); - bufOffset = normalElement.getSize(); + bufOffset += normalElement.getSize(); vertexFormat->setAttribute(gpu::Stream::TANGENT, tangentChannel, normalElement, bufOffset); - bufOffset = normalElement.getSize(); + bufOffset += normalElement.getSize(); if (!interleaveNormalsTangents) { bufOffset = 0; } @@ -895,7 +876,7 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { vertexBufferStream->addBuffer(attribBuffer, 0, vStride); } - // MEsh vertex format and vertex stream is ready + // Mesh vertex format and vertex stream is ready mesh->setVertexFormatAndStream(vertexFormat, vertexBufferStream); // Index and Part Buffers diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp index 6ce25bc56c..21553dc2c7 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp @@ -268,9 +268,18 @@ void GLBackend::updateInput() { auto offset = _input._bufferOffsets.data(); auto stride = _input._bufferStrides.data(); + // Profile the count of buffers to update and use it to short cut the for loop + int numInvalids = _input._invalidBuffers.count(); + _stats._ISNumInputBufferChanges += numInvalids; + PROFILE_COUNTER_IF_CHANGED(render_gpu, "numInputBuffersbound", int, numInvalids); + for (GLuint buffer = 0; buffer < _input._buffers.size(); buffer++, vbo++, offset++, stride++) { if (_input._invalidBuffers.test(buffer)) { glBindVertexBuffer(buffer, (*vbo), (*offset), (GLsizei)(*stride)); + numInvalids--; + if (numInvalids <= 0) { + break; + } } } diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp index 9dcb08f0b7..30e393630a 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp @@ -78,7 +78,10 @@ void GL41Backend::updateInput() { const Stream::Format::AttributeMap& attributes = _input._format->getAttributes(); auto& inputChannels = _input._format->getChannels(); - _stats._ISNumInputBufferChanges++; + _stats._ISNumInputBufferChanges += _input._invalidBuffers.count(); + + // Profile the count of buffers to update + PROFILE_COUNTER_IF_CHANGED(render_gpu, "numInputBuffersbound", int, _input._invalidBuffers.count()); GLuint boundVBO = 0; for (auto& channelIt : inputChannels) { diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp index c914b9f84d..de4989eb32 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp @@ -27,8 +27,6 @@ void GL45Backend::resetInputStage() { } void GL45Backend::updateInput() { - // PROFILE_RANGE(render_gpu, __FUNCTION__); - bool isStereoNow = isStereo(); // track stereo state change potentially happening wihtout changing the input format // this is a rare case requesting to invalid the format @@ -131,21 +129,26 @@ void GL45Backend::updateInput() { } if (_input._invalidBuffers.any()) { - // PROFILE_RANGE(render_gpu, "bindInputBuffers"); auto vbo = _input._bufferVBOs.data(); auto offset = _input._bufferOffsets.data(); auto stride = _input._bufferStrides.data(); - int numSet = 0; + // Profile the count of buffers to update and use it to short cut the for loop + int numInvalids = _input._invalidBuffers.count(); + _stats._ISNumInputBufferChanges += numInvalids; + PROFILE_COUNTER_IF_CHANGED(render_gpu, "numInputBuffersbound", int, numInvalids); + auto numBuffers = _input._buffers.size(); for (GLuint buffer = 0; buffer < numBuffers; buffer++, vbo++, offset++, stride++) { if (_input._invalidBuffers.test(buffer)) { glBindVertexBuffer(buffer, (*vbo), (*offset), (GLsizei)(*stride)); - numSet++; + numInvalids--; + if (numInvalids <= 0) { + break; + } } } - PROFILE_COUNTER_IF_CHANGED(render_gpu, "numVBSbound", int, numSet); _input._invalidBuffers.reset(); (void)CHECK_GL_ERROR(); From 77bb6fa4d54b0f7cccdcd6aa6b86d7fd58b963b4 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Wed, 5 Sep 2018 11:53:49 -0700 Subject: [PATCH 259/545] adding position to try again zone; updating whitespace --- interface/resources/serverless/redirect.json | 44 ++++++++++---------- libraries/networking/src/AddressManager.cpp | 4 +- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/interface/resources/serverless/redirect.json b/interface/resources/serverless/redirect.json index 48b1a7078f..64cb4d8a3f 100644 --- a/interface/resources/serverless/redirect.json +++ b/interface/resources/serverless/redirect.json @@ -9,39 +9,39 @@ "clientOnly": false, "collidesWith": "static,dynamic,kinematic,otherAvatar,", "collisionMask": 23, - "created": "2018-09-05T00:40:03Z", + "created": "2018-09-05T18:13:00Z", "dimensions": { - "blue": 0.8660923838615417, - "green": 1.921838402748108, - "red": 1.2744625806808472, - "x": 1.2744625806808472, - "y": 1.921838402748108, - "z": 0.8660923838615417 + "blue": 1.159199833869934, + "green": 2.8062009811401367, + "red": 1.6216505765914917, + "x": 1.6216505765914917, + "y": 2.8062009811401367, + "z": 1.159199833869934 }, - "id": "{781e26c7-ecfa-44b2-b7ef-4e3278787fbc}", - "lastEdited": 1536108183362142, - "lastEditedBy": "{4656d4a8-5e61-4230-ab34-2888d7945bd6}", + "id": "{d0ed60b8-9174-4c56-8e78-2c5399329ae0}", + "lastEdited": 1536171372916208, + "lastEditedBy": "{151cb20e-715a-4c80-aa0d-5b58b1c8a0c9}", "locked": true, "name": "Try Again Zone", "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", "position": { - "blue": 4.225754737854004, - "green": 1.7677892446517944, - "red": 2.778148889541626, - "x": 2.778148889541626, - "y": 1.7677892446517944, - "z": 4.225754737854004 + "blue":4.015342712402344, + "green":1.649999976158142, + "red":2.00921893119812, + "x":2.00921893119812, + "y":1.649999976158142, + "z":4.015342712402344 }, "queryAACube": { - "scale": 2.4632973670959473, - "x": 1.5465002059936523, - "y": 0.5361405611038208, - "z": 2.9941060543060303 + "scale": 3.4421300888061523, + "x": 1.6001315116882324, + "y": -0.07100248336791992, + "z": 0.14220571517944336 }, "rotation": { - "w": 0.9743700623512268, + "w": 0.9914448857307434, "x": 0, - "y": -0.22495104372501373, + "y": -0.13052619993686676, "z": 0 }, "script": "https://hifi-content.s3.amazonaws.com/wayne/404redirectionScripts/zoneTryAgainEntityScript.js", diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 1b258e14b1..6ebd516063 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -259,8 +259,8 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) { UserActivityLogger::getInstance().wentTo(trigger, URL_TYPE_USER, lookupUrl.toString()); - // save the last visited domain URL. - _lastVisitedURL = lookupUrl; + // save the last visited domain URL. + _lastVisitedURL = lookupUrl; // in case we're failing to connect to where we thought this user was // store their username as previous lookup so we can refresh their location via API From 133ac0662a57f8c35505fbd8327ba84b101aa705 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 10 Aug 2018 16:06:08 -0700 Subject: [PATCH 260/545] Move entity list qml to scripts dir --- scripts/system/libraries/EditEntityList.qml | 11 +++++++++++ scripts/system/libraries/entityList.js | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 scripts/system/libraries/EditEntityList.qml diff --git a/scripts/system/libraries/EditEntityList.qml b/scripts/system/libraries/EditEntityList.qml new file mode 100644 index 0000000000..d8099cb670 --- /dev/null +++ b/scripts/system/libraries/EditEntityList.qml @@ -0,0 +1,11 @@ +import QtQuick 2.7 +import QtQuick.Controls 2.2 +import QtWebChannel 1.0 +import QtGraphicalEffects 1.0 +import "qrc:///qml/controls" as HifiControls + +HifiControls.WebView { + id: entityListToolWebView + url: Qt.resolvedUrl("../html/entityList.html") + enabled: true +} diff --git a/scripts/system/libraries/entityList.js b/scripts/system/libraries/entityList.js index 678b2eeb0b..cd0c712148 100644 --- a/scripts/system/libraries/entityList.js +++ b/scripts/system/libraries/entityList.js @@ -20,7 +20,7 @@ EntityListTool = function(shouldUseEditTabletApp) { var ENTITY_LIST_WIDTH = 495; var MAX_DEFAULT_CREATE_TOOLS_HEIGHT = 778; var entityListWindow = new CreateWindow( - Script.resourcesPath() + "qml/hifi/tablet/EditEntityList.qml", + Script.resolvePath("EditEntityList.qml"), 'Entity List', 'com.highfidelity.create.entityListWindow', function () { From f6ac755bae0a6ce47b49d6445afb07fabefa40de Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 13 Aug 2018 08:47:37 -0700 Subject: [PATCH 261/545] Add profiling to edit.js fof the entity list --- scripts/system/html/js/entityList.js | 54 ++++++---- scripts/system/libraries/entityList.js | 130 ++++++++++++++----------- 2 files changed, 109 insertions(+), 75 deletions(-) diff --git a/scripts/system/html/js/entityList.js b/scripts/system/html/js/entityList.js index 5cd5f6d610..779100affb 100644 --- a/scripts/system/html/js/entityList.js +++ b/scripts/system/html/js/entityList.js @@ -23,6 +23,18 @@ const DELETE = 46; // Key code for the delete key. const KEY_P = 80; // Key code for letter p used for Parenting hotkey. const MAX_ITEMS = Number.MAX_VALUE; // Used to set the max length of the list of discovered entities. +var profileIndent = ''; +PROFILE = function(name, fn, args) { + EventBridge.emitWebEvent("PROFILE-Web " + profileIndent + "(" + name + ") Begin"); + var previousIndent = profileIndent; + profileIndent += ' '; + var before = Date.now(); + fn.apply(this, args); + var delta = Date.now() - before; + profileIndent = previousIndent; + EventBridge.emitWebEvent("PROFILE-Web " + profileIndent + "(" + name + ") End " + delta + "ms"); +} + debugPrint = function (message) { console.log(message); }; @@ -363,27 +375,29 @@ function loaded() { refreshEntities(); } } else if (data.type === "update" && data.selectedIDs !== undefined) { - var newEntities = data.entities; - if (newEntities && newEntities.length == 0) { - elNoEntitiesMessage.style.display = "block"; - elFooter.firstChild.nodeValue = "0 entities found"; - } else if (newEntities) { - elNoEntitiesMessage.style.display = "none"; - for (var i = 0; i < newEntities.length; i++) { - var id = newEntities[i].id; - addEntity(id, newEntities[i].name, newEntities[i].type, newEntities[i].url, - newEntities[i].locked ? LOCKED_GLYPH : null, - newEntities[i].visible ? VISIBLE_GLYPH : null, - newEntities[i].verticesCount, newEntities[i].texturesCount, newEntities[i].texturesSize, - newEntities[i].hasTransparent ? TRANSPARENCY_GLYPH : null, - newEntities[i].isBaked ? BAKED_GLYPH : null, - newEntities[i].drawCalls, - newEntities[i].hasScript ? SCRIPT_GLYPH : null); + PROFILE("update", function() { + var newEntities = data.entities; + if (newEntities && newEntities.length == 0) { + elNoEntitiesMessage.style.display = "block"; + elFooter.firstChild.nodeValue = "0 entities found"; + } else if (newEntities) { + elNoEntitiesMessage.style.display = "none"; + for (var i = 0; i < newEntities.length; i++) { + var id = newEntities[i].id; + addEntity(id, newEntities[i].name, newEntities[i].type, newEntities[i].url, + newEntities[i].locked ? LOCKED_GLYPH : null, + newEntities[i].visible ? VISIBLE_GLYPH : null, + newEntities[i].verticesCount, newEntities[i].texturesCount, newEntities[i].texturesSize, + newEntities[i].hasTransparent ? TRANSPARENCY_GLYPH : null, + newEntities[i].isBaked ? BAKED_GLYPH : null, + newEntities[i].drawCalls, + newEntities[i].hasScript ? SCRIPT_GLYPH : null); + } + updateSelectedEntities(data.selectedIDs); + scheduleRefreshEntityList(); + resize(); } - updateSelectedEntities(data.selectedIDs); - scheduleRefreshEntityList(); - resize(); - } + }); } else if (data.type === "removeEntities" && data.deletedIDs !== undefined && data.selectedIDs !== undefined) { removeEntities(data.deletedIDs); updateSelectedEntities(data.selectedIDs); diff --git a/scripts/system/libraries/entityList.js b/scripts/system/libraries/entityList.js index cd0c712148..b52a31760f 100644 --- a/scripts/system/libraries/entityList.js +++ b/scripts/system/libraries/entityList.js @@ -11,6 +11,18 @@ /* global EntityListTool, Tablet, selectionManager, Entities, Camera, MyAvatar, Vec3, Menu, Messages, cameraManager, MENU_EASE_ON_FOCUS, deleteSelectedEntities, toggleSelectedEntitiesLocked, toggleSelectedEntitiesVisible */ +var profileIndent = ''; +PROFILE = function(name, fn, args) { + console.log("PROFILE-Script " + profileIndent + "(" + name + ") Begin"); + var previousIndent = profileIndent; + profileIndent += ' '; + var before = Date.now(); + fn.apply(this, args); + var delta = Date.now() - before; + profileIndent = previousIndent; + console.log("PROFILE-Script " + profileIndent + "(" + name + ") End " + delta + "ms"); +} + EntityListTool = function(shouldUseEditTabletApp) { var that = {}; @@ -66,11 +78,16 @@ EntityListTool = function(shouldUseEditTabletApp) { that.setVisible(false); function emitJSONScriptEvent(data) { - var dataString = JSON.stringify(data); - webView.emitScriptEvent(dataString); - if (entityListWindow.window) { - entityListWindow.window.emitScriptEvent(dataString); - } + var dataString; + PROFILE("Script-JSON.stringify", function() { + dataString = JSON.stringify(data); + }); + PROFILE("Script-emitScriptEvent", function() { + webView.emitScriptEvent(dataString); + if (entityListWindow.window) { + entityListWindow.window.emitScriptEvent(dataString); + } + }); } that.toggleVisible = function() { @@ -116,59 +133,61 @@ EntityListTool = function(shouldUseEditTabletApp) { } that.sendUpdate = function() { - var entities = []; + PROFILE('Script-sendUpdate', function() { + var entities = []; - var ids; - if (filterInView) { - ids = Entities.findEntitiesInFrustum(Camera.frustum); - } else { - ids = Entities.findEntities(MyAvatar.position, searchRadius); - } - - var cameraPosition = Camera.position; - for (var i = 0; i < ids.length; i++) { - var id = ids[i]; - var properties = Entities.getEntityProperties(id); - - if (!filterInView || Vec3.distance(properties.position, cameraPosition) <= searchRadius) { - var url = ""; - if (properties.type === "Model") { - url = properties.modelURL; - } else if (properties.type === "Material") { - url = properties.materialURL; - } - entities.push({ - id: id, - name: properties.name, - type: properties.type, - url: url, - locked: properties.locked, - visible: properties.visible, - verticesCount: (properties.renderInfo !== undefined ? - valueIfDefined(properties.renderInfo.verticesCount) : ""), - texturesCount: (properties.renderInfo !== undefined ? - valueIfDefined(properties.renderInfo.texturesCount) : ""), - texturesSize: (properties.renderInfo !== undefined ? - valueIfDefined(properties.renderInfo.texturesSize) : ""), - hasTransparent: (properties.renderInfo !== undefined ? - valueIfDefined(properties.renderInfo.hasTransparent) : ""), - isBaked: properties.type === "Model" ? url.toLowerCase().endsWith(".baked.fbx") : false, - drawCalls: (properties.renderInfo !== undefined ? - valueIfDefined(properties.renderInfo.drawCalls) : ""), - hasScript: properties.script !== "" - }); + var ids; + if (filterInView) { + ids = Entities.findEntitiesInFrustum(Camera.frustum); + } else { + ids = Entities.findEntities(MyAvatar.position, searchRadius); } - } - var selectedIDs = []; - for (var j = 0; j < selectionManager.selections.length; j++) { - selectedIDs.push(selectionManager.selections[j]); - } + var cameraPosition = Camera.position; + for (var i = 0; i < ids.length; i++) { + var id = ids[i]; + var properties = Entities.getEntityProperties(id); - emitJSONScriptEvent({ - type: "update", - entities: entities, - selectedIDs: selectedIDs, + if (!filterInView || Vec3.distance(properties.position, cameraPosition) <= searchRadius) { + var url = ""; + if (properties.type === "Model") { + url = properties.modelURL; + } else if (properties.type === "Material") { + url = properties.materialURL; + } + entities.push({ + id: id, + name: properties.name, + type: properties.type, + url: url, + locked: properties.locked, + visible: properties.visible, + verticesCount: (properties.renderInfo !== undefined ? + valueIfDefined(properties.renderInfo.verticesCount) : ""), + texturesCount: (properties.renderInfo !== undefined ? + valueIfDefined(properties.renderInfo.texturesCount) : ""), + texturesSize: (properties.renderInfo !== undefined ? + valueIfDefined(properties.renderInfo.texturesSize) : ""), + hasTransparent: (properties.renderInfo !== undefined ? + valueIfDefined(properties.renderInfo.hasTransparent) : ""), + isBaked: properties.type === "Model" ? url.toLowerCase().endsWith(".baked.fbx") : false, + drawCalls: (properties.renderInfo !== undefined ? + valueIfDefined(properties.renderInfo.drawCalls) : ""), + hasScript: properties.script !== "" + }); + } + } + + var selectedIDs = []; + for (var j = 0; j < selectionManager.selections.length; j++) { + selectedIDs.push(selectionManager.selections[j]); + } + + emitJSONScriptEvent({ + type: "update", + entities: entities, + selectedIDs: selectedIDs, + }); }); }; @@ -186,7 +205,8 @@ EntityListTool = function(shouldUseEditTabletApp) { try { data = JSON.parse(data); } catch(e) { - print("entityList.js: Error parsing JSON: " + e.name + " data " + data); + console.log(data); + //print("entityList.js: Error parsing JSON: " + e.name + " data " + data); return; } From f2cc2f148597ecaff79ab5ab85c920fde9ad1a11 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 13 Aug 2018 13:21:00 -0700 Subject: [PATCH 262/545] Update entity list UI to be updated in a single batch --- scripts/system/html/entityList.html | 3 +- scripts/system/html/js/entityList.js | 127 ++++++++++++++++++--------- 2 files changed, 86 insertions(+), 44 deletions(-) diff --git a/scripts/system/html/entityList.html b/scripts/system/html/entityList.html index 7906a3c97f..0802c23b71 100644 --- a/scripts/system/html/entityList.html +++ b/scripts/system/html/entityList.html @@ -10,8 +10,9 @@ - + + diff --git a/scripts/system/html/js/entityList.js b/scripts/system/html/js/entityList.js index 779100affb..17a1b26bbf 100644 --- a/scripts/system/html/js/entityList.js +++ b/scripts/system/html/js/entityList.js @@ -23,16 +23,22 @@ const DELETE = 46; // Key code for the delete key. const KEY_P = 80; // Key code for letter p used for Parenting hotkey. const MAX_ITEMS = Number.MAX_VALUE; // Used to set the max length of the list of discovered entities. +log = function(msg) { + EventBridge.emitWebEvent(msg); +} + var profileIndent = ''; PROFILE = function(name, fn, args) { - EventBridge.emitWebEvent("PROFILE-Web " + profileIndent + "(" + name + ") Begin"); + log("PROFILE-Web " + profileIndent + "(" + name + ") Begin"); + console.log("PROFILE-Web " + profileIndent + "(" + name + ") Begin"); var previousIndent = profileIndent; profileIndent += ' '; var before = Date.now(); fn.apply(this, args); var delta = Date.now() - before; profileIndent = previousIndent; - EventBridge.emitWebEvent("PROFILE-Web " + profileIndent + "(" + name + ") End " + delta + "ms"); + log("PROFILE-Web " + profileIndent + "(" + name + ") End " + delta + "ms"); + console.log("PROFILE-Web " + profileIndent + "(" + name + ") End " + delta + "ms"); } debugPrint = function (message) { @@ -168,44 +174,89 @@ function loaded() { return number ? number : ""; } - function addEntity(id, name, type, url, locked, visible, verticesCount, texturesCount, texturesSize, hasTransparent, - isBaked, drawCalls, hasScript) { + function getFilename(url) { + let urlParts = url.split('/'); + return urlParts[urlParts.length - 1]; + } - var urlParts = url.split('/'); - var filename = urlParts[urlParts.length - 1]; + //function addEntity( + //id, name, type, url, locked, visible, verticesCount, + //texturesCount, texturesSize, hasTransparent, + //isBaked, drawCalls, hasScript) { + function addEntities(entityData) { + const IMAGE_MODEL_NAME = 'default-image-model.fbx'; - var IMAGE_MODEL_NAME = 'default-image-model.fbx'; + let newEntities = entityData.filter(function(entity) { + if (entity.id in entities) { + var item = entities[entity.id].item; + item.values({ + name: entity.name, + url: getFilename(entity.url), + locked: entity.locked, + visible: entity.visible + }); + return false; + } + return true; + }); - if (filename === IMAGE_MODEL_NAME) { - type = "Image"; + if (newEntities.length === 0) { + return; } - if (entities[id] === undefined) { - entityList.add([{ - id: id, name: name, type: type, url: filename, locked: locked, visible: visible, - verticesCount: displayIfNonZero(verticesCount), texturesCount: displayIfNonZero(texturesCount), - texturesSize: decimalMegabytes(texturesSize), hasTransparent: hasTransparent, - isBaked: isBaked, drawCalls: displayIfNonZero(drawCalls), hasScript: hasScript - }], + newEntities = newEntities.map(function(entity) { + let type = entity.type; + let filename = getFilename(entity.url); + if (filename === IMAGE_MODEL_NAME) { + type = "Image"; + } + return { + id: entity.id, + name: entity.name, + type: type, + url: filename, + fullUrl: entity.url, + locked: entity.locked ? LOCKED_GLYPH : null, + visible: entity.visible ? VISIBLE_GLYPH : null, + verticesCount: displayIfNonZero(entity.verticesCount), + texturesCount: displayIfNonZero(entity.texturesCount), + texturesSize: decimalMegabytes(entity.texturesSize), + hasTransparent: entity.hasTransparent ? TRANSPARENCY_GLYPH : null, + isBaked: entity.isBaked ? BAKED_GLYPH : null, + drawCalls: displayIfNonZero(entity.drawCalls), + hasScript: entity.hasScript ? SCRIPT_GLYPH : null + } + }); + //newEntities = newEntities.splice(newEntities.length - 10); + console.log("Adding: " + newEntities.length); + + let size = 2000; + let sets = Math.ceil(newEntities.length / size); + for (let i = 0; i < sets; i++) { + + console.log(Date.now(), "Adding", i * size, (i + 1) * size); + entityList.add(newEntities.splice(i * size, (i + 1) * size), function (items) { - var currentElement = items[0].elm; - var id = items[0]._values.id; - entities[id] = { - id: id, - name: name, - el: currentElement, - item: items[0] - }; - currentElement.setAttribute('id', 'entity_' + id); - currentElement.setAttribute('title', url); - currentElement.dataset.entityId = id; - currentElement.onclick = onRowClicked; - currentElement.ondblclick = onRowDoubleClicked; + console.log(Date.now(), "added: " + items.length); + items.forEach(function(item) { + var currentElement = item.elm; + var values = item._values; + + entities[values.id] = { + id: values.id, + name: values.name, + el: currentElement, + item: item + }; + currentElement.setAttribute('id', 'entity_' + values.id); + currentElement.setAttribute('title', values.fullUrl); + currentElement.dataset.entityId = values.id; + currentElement.onclick = onRowClicked; + currentElement.ondblclick = onRowDoubleClicked; + }); }); - } else { - var item = entities[id].item; - item.values({ name: name, url: filename, locked: locked, visible: visible }); } + console.log(Date.now(), "DONE"); } function removeEntities(deletedIDs) { @@ -382,17 +433,7 @@ function loaded() { elFooter.firstChild.nodeValue = "0 entities found"; } else if (newEntities) { elNoEntitiesMessage.style.display = "none"; - for (var i = 0; i < newEntities.length; i++) { - var id = newEntities[i].id; - addEntity(id, newEntities[i].name, newEntities[i].type, newEntities[i].url, - newEntities[i].locked ? LOCKED_GLYPH : null, - newEntities[i].visible ? VISIBLE_GLYPH : null, - newEntities[i].verticesCount, newEntities[i].texturesCount, newEntities[i].texturesSize, - newEntities[i].hasTransparent ? TRANSPARENCY_GLYPH : null, - newEntities[i].isBaked ? BAKED_GLYPH : null, - newEntities[i].drawCalls, - newEntities[i].hasScript ? SCRIPT_GLYPH : null); - } + addEntities(newEntities); updateSelectedEntities(data.selectedIDs); scheduleRefreshEntityList(); resize(); From a9a5bf1e972cf654e34d4949348720ad9b9e28b8 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 20 Aug 2018 13:11:22 -0700 Subject: [PATCH 263/545] Replace entity list UI with custom, brute-force solution --- scripts/system/html/js/entityList.js | 243 ++++++++++++++----------- scripts/system/libraries/entityList.js | 4 + 2 files changed, 140 insertions(+), 107 deletions(-) diff --git a/scripts/system/html/js/entityList.js b/scripts/system/html/js/entityList.js index 17a1b26bbf..c30aac2a7f 100644 --- a/scripts/system/html/js/entityList.js +++ b/scripts/system/html/js/entityList.js @@ -6,12 +6,8 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -var entities = {}; -var selectedEntities = []; -var currentSortColumn = 'type'; -var currentSortOrder = 'des'; -var entityList = null; -var refreshEntityListTimer = null; +const ASCENDING_SORT = 1; +const DESCENDING_SORT = -1; const ASCENDING_STRING = '▴'; const DESCENDING_STRING = '▾'; const LOCKED_GLYPH = ""; @@ -23,6 +19,30 @@ const DELETE = 46; // Key code for the delete key. const KEY_P = 80; // Key code for letter p used for Parenting hotkey. const MAX_ITEMS = Number.MAX_VALUE; // Used to set the max length of the list of discovered entities. +const COMPARE_ASCENDING = function(a, b) { + let va = a[currentSortColumn]; + let vb = b[currentSortColumn]; + + if (va < vb) { + return -1; + } else if (va > vb) { + return 1; + } + return 0; +} +const COMPARE_DESCENDING = function(a, b) { + return COMPARE_ASCENDING(b, a); +} + +var entities = {}; +var entityCount = 0; +// Raw entity data sent from script +let entityData = [] +var selectedEntities = []; +var currentSortColumn = 'type'; +var currentSortOrder = ASCENDING_SORT; +var refreshEntityListTimer = null; + log = function(msg) { EventBridge.emitWebEvent(msg); } @@ -47,8 +67,6 @@ debugPrint = function (message) { function loaded() { openEventBridge(function() { - entityList = new List('entity-list', { valueNames: ['name', 'type', 'url', 'locked', 'visible'], page: MAX_ITEMS}); - entityList.clear(); elEntityTable = document.getElementById("entity-table"); elEntityTableBody = document.getElementById("entity-table-body"); elRefresh = document.getElementById("refresh"); @@ -107,10 +125,12 @@ function loaded() { }; function onRowClicked(clickEvent) { - var id = this.dataset.entityId; - var selection = [this.dataset.entityId]; + let entityID = this.dataset.entityID; + console.log("CLICKED", entityID, this); + //return; + var selection = [entityID]; if (clickEvent.ctrlKey) { - var selectedIndex = selectedEntities.indexOf(id); + var selectedIndex = selectedEntities.indexOf(entityID); if (selectedIndex >= 0) { selection = selectedEntities; selection.splice(selectedIndex, 1) @@ -121,7 +141,7 @@ function loaded() { var previousItemFound = -1; var clickedItemFound = -1; for (var entity in entityList.visibleItems) { - if (clickedItemFound === -1 && this.dataset.entityId == entityList.visibleItems[entity].values().id) { + if (clickedItemFound === -1 && entityID == entityList.visibleItems[entity].values().id) { clickedItemFound = entity; } else if(previousItemFound === -1 && selectedEntities[0] == entityList.visibleItems[entity].values().id) { previousItemFound = entity; @@ -143,6 +163,12 @@ function loaded() { } } + selectedEntities.forEach(function(entityID) { + if (selection.indexOf(entityID) === -1) { + entities[entityID].el.className = ''; + } + }); + selectedEntities = selection; this.className = 'selected'; @@ -160,7 +186,7 @@ function loaded() { EventBridge.emitWebEvent(JSON.stringify({ type: "selectionUpdate", focus: true, - entityIds: [this.dataset.entityId], + entityIds: [this.dataset.entityID], })); } @@ -179,90 +205,88 @@ function loaded() { return urlParts[urlParts.length - 1]; } - //function addEntity( - //id, name, type, url, locked, visible, verticesCount, - //texturesCount, texturesSize, hasTransparent, - //isBaked, drawCalls, hasScript) { - function addEntities(entityData) { + function refreshEntityList() { const IMAGE_MODEL_NAME = 'default-image-model.fbx'; - let newEntities = entityData.filter(function(entity) { - if (entity.id in entities) { - var item = entities[entity.id].item; - item.values({ + PROFILE("sort", function() { + let cmp = currentSortOrder === ASCENDING_SORT ? COMPARE_ASCENDING : COMPARE_DESCENDING; + console.log("Doing sort", currentSortColumn, currentSortOrder); + entityData.sort(cmp); + }); + + entities = {}; + + let newEntities; + PROFILE("map-data", function() { + newEntities = entityData.map(function(entity) { + let type = entity.type; + let filename = getFilename(entity.url); + if (filename === IMAGE_MODEL_NAME) { + type = "Image"; + } + return { + id: entity.id, name: entity.name, - url: getFilename(entity.url), - locked: entity.locked, - visible: entity.visible - }); - return false; - } - return true; - }); - - if (newEntities.length === 0) { - return; - } - - newEntities = newEntities.map(function(entity) { - let type = entity.type; - let filename = getFilename(entity.url); - if (filename === IMAGE_MODEL_NAME) { - type = "Image"; - } - return { - id: entity.id, - name: entity.name, - type: type, - url: filename, - fullUrl: entity.url, - locked: entity.locked ? LOCKED_GLYPH : null, - visible: entity.visible ? VISIBLE_GLYPH : null, - verticesCount: displayIfNonZero(entity.verticesCount), - texturesCount: displayIfNonZero(entity.texturesCount), - texturesSize: decimalMegabytes(entity.texturesSize), - hasTransparent: entity.hasTransparent ? TRANSPARENCY_GLYPH : null, - isBaked: entity.isBaked ? BAKED_GLYPH : null, - drawCalls: displayIfNonZero(entity.drawCalls), - hasScript: entity.hasScript ? SCRIPT_GLYPH : null - } - }); - //newEntities = newEntities.splice(newEntities.length - 10); - console.log("Adding: " + newEntities.length); - - let size = 2000; - let sets = Math.ceil(newEntities.length / size); - for (let i = 0; i < sets; i++) { - - console.log(Date.now(), "Adding", i * size, (i + 1) * size); - entityList.add(newEntities.splice(i * size, (i + 1) * size), - function (items) { - console.log(Date.now(), "added: " + items.length); - items.forEach(function(item) { - var currentElement = item.elm; - var values = item._values; - - entities[values.id] = { - id: values.id, - name: values.name, - el: currentElement, - item: item - }; - currentElement.setAttribute('id', 'entity_' + values.id); - currentElement.setAttribute('title', values.fullUrl); - currentElement.dataset.entityId = values.id; - currentElement.onclick = onRowClicked; - currentElement.ondblclick = onRowDoubleClicked; - }); + type: type, + url: filename, + fullUrl: entity.url, + locked: entity.locked ? LOCKED_GLYPH : null, + visible: entity.visible ? VISIBLE_GLYPH : null, + verticesCount: displayIfNonZero(entity.verticesCount), + texturesCount: displayIfNonZero(entity.texturesCount), + texturesSize: decimalMegabytes(entity.texturesSize), + hasTransparent: entity.hasTransparent ? TRANSPARENCY_GLYPH : null, + isBaked: entity.isBaked ? BAKED_GLYPH : null, + drawCalls: displayIfNonZero(entity.drawCalls), + hasScript: entity.hasScript ? SCRIPT_GLYPH : null + } }); - } - console.log(Date.now(), "DONE"); + }); + + console.log("Adding: " + newEntities.length); + + elEntityTableBody.innerHTML = ''; + + entities = {}; + + PROFILE("update-dom", function() { + newEntities.forEach(function(entity) { + let row = document.createElement('tr'); + row.dataset.entityID = entity.id; + row.attributes.title = entity.fullUrl; + function addColumn(cls, text) { + let col = document.createElement('td'); + col.className = cls; + col.innerText = text; + row.append(col); + } + addColumn('type', entity.type); + addColumn('name', entity.name); + addColumn('url', entity.url); + addColumn('locked glyph', entity.locked); + addColumn('visible glyph', entity.visible); + addColumn('verticesCount', entity.verticesCount); + addColumn('texturesCount', entity.texturesCount); + addColumn('texturesSize', entity.texturesSize); + addColumn('hasTransparent glyph', entity.hasTransparent); + addColumn('isBaked glyph', entity.isBaked); + addColumn('drawCalls', entity.drawCalls); + addColumn('hasScript glyph', entity.hasScript); + elEntityTableBody.append(row); + row.addEventListener('click', onRowClicked); + row.addEventListener('dblclick', onRowDoubleClicked); + entities[entity.id] = { el: row }; + }); + + }); } function removeEntities(deletedIDs) { + return; for (i = 0, length = deletedIDs.length; i < length; i++) { - delete entities[deletedIDs[i]]; - entityList.remove("id", deletedIDs[i]); + let id = deletedIDs[i]; + entities[id].el.remove(); + delete entities[id]; } } @@ -276,7 +300,6 @@ function loaded() { function clearEntities() { entities = {}; - entityList.clear(); refreshFooter(); } @@ -295,15 +318,19 @@ function loaded() { hasScript: document.querySelector('#entity-hasScript .sort-order'), } function setSortColumn(column) { - if (currentSortColumn == column) { - currentSortOrder = currentSortOrder == "asc" ? "desc" : "asc"; - } else { - elSortOrder[currentSortColumn].innerHTML = ""; - currentSortColumn = column; - currentSortOrder = "asc"; - } - elSortOrder[column].innerHTML = currentSortOrder == "asc" ? ASCENDING_STRING : DESCENDING_STRING; - entityList.sort(currentSortColumn, { order: currentSortOrder }); + PROFILE("set-sort-column", function() { + if (currentSortColumn == column) { + currentSortOrder *= -1; + } else { + elSortOrder[currentSortColumn].innerHTML = ""; + currentSortColumn = column; + currentSortOrder = ASCENDING_SORT; + } + elSortOrder[column].innerHTML = currentSortOrder == ASCENDING_SORT ? ASCENDING_STRING : DESCENDING_STRING; + + //entityList.sort(currentSortColumn, { order: currentSortOrder }); + refreshEntityList(); + }); } setSortColumn('type'); @@ -313,21 +340,22 @@ function loaded() { } function refreshFooter() { + return; if (selectedEntities.length > 1) { elFooter.firstChild.nodeValue = selectedEntities.length + " entities selected"; } else if (selectedEntities.length === 1) { elFooter.firstChild.nodeValue = "1 entity selected"; - } else if (entityList.visibleItems.length === 1) { + } else if (entityCount === 1) { elFooter.firstChild.nodeValue = "1 entity found"; } else { - elFooter.firstChild.nodeValue = entityList.visibleItems.length + " entities found"; + elFooter.firstChild.nodeValue = entityCount + " entities found"; } } function refreshEntityListObject() { refreshEntityListTimer = null; - entityList.sort(currentSortColumn, { order: currentSortOrder }); - entityList.search(elFilter.value); + //entityList.sort(currentSortColumn, { order: currentSortOrder }); + //entityList.search(elFilter.value); refreshFooter(); } @@ -433,10 +461,11 @@ function loaded() { elFooter.firstChild.nodeValue = "0 entities found"; } else if (newEntities) { elNoEntitiesMessage.style.display = "none"; - addEntities(newEntities); - updateSelectedEntities(data.selectedIDs); - scheduleRefreshEntityList(); - resize(); + entityData = newEntities; + refreshEntityList(); + //updateSelectedEntities(data.selectedIDs); + //scheduleRefreshEntityList(); + //resize(); } }); } else if (data.type === "removeEntities" && data.deletedIDs !== undefined && data.selectedIDs !== undefined) { diff --git a/scripts/system/libraries/entityList.js b/scripts/system/libraries/entityList.js index b52a31760f..1651eaedcc 100644 --- a/scripts/system/libraries/entityList.js +++ b/scripts/system/libraries/entityList.js @@ -137,13 +137,16 @@ EntityListTool = function(shouldUseEditTabletApp) { var entities = []; var ids; + PROFILE("findEntities", function() { if (filterInView) { ids = Entities.findEntitiesInFrustum(Camera.frustum); } else { ids = Entities.findEntities(MyAvatar.position, searchRadius); } + }); var cameraPosition = Camera.position; + PROFILE("getProperties", function() { for (var i = 0; i < ids.length; i++) { var id = ids[i]; var properties = Entities.getEntityProperties(id); @@ -177,6 +180,7 @@ EntityListTool = function(shouldUseEditTabletApp) { }); } } + }); var selectedIDs = []; for (var j = 0; j < selectionManager.selections.length; j++) { From 739530cb85c75344e18732cd6a057cfe6b40191f Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 21 Aug 2018 09:30:19 -0700 Subject: [PATCH 264/545] Limit Entity List to only getting the properties it needs --- scripts/system/libraries/entityList.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/system/libraries/entityList.js b/scripts/system/libraries/entityList.js index 1651eaedcc..3900260d0c 100644 --- a/scripts/system/libraries/entityList.js +++ b/scripts/system/libraries/entityList.js @@ -82,6 +82,7 @@ EntityListTool = function(shouldUseEditTabletApp) { PROFILE("Script-JSON.stringify", function() { dataString = JSON.stringify(data); }); + console.log("Length: ", dataString.length, data.type); PROFILE("Script-emitScriptEvent", function() { webView.emitScriptEvent(dataString); if (entityListWindow.window) { @@ -149,7 +150,9 @@ EntityListTool = function(shouldUseEditTabletApp) { PROFILE("getProperties", function() { for (var i = 0; i < ids.length; i++) { var id = ids[i]; - var properties = Entities.getEntityProperties(id); + //var properties = Entities.getEntityProperties(id); + var properties = Entities.getEntityProperties(id, ['name', 'type', 'locked', + 'visible', 'renderInfo', 'type', 'modelURL', 'materialURL', 'script']); if (!filterInView || Vec3.distance(properties.position, cameraPosition) <= searchRadius) { var url = ""; From 335f66d165f2c533def5f10e17ca17f3395117a0 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 5 Sep 2018 14:28:57 -0700 Subject: [PATCH 265/545] Add filtering support to entity list --- scripts/system/html/entityList.html | 1 + scripts/system/html/js/entityList.js | 237 +++++++++++++++------------ 2 files changed, 131 insertions(+), 107 deletions(-) diff --git a/scripts/system/html/entityList.html b/scripts/system/html/entityList.html index 0802c23b71..cb95dffc5f 100644 --- a/scripts/system/html/entityList.html +++ b/scripts/system/html/entityList.html @@ -9,6 +9,7 @@ --> + diff --git a/scripts/system/html/js/entityList.js b/scripts/system/html/js/entityList.js index c30aac2a7f..ebf31d5d36 100644 --- a/scripts/system/html/js/entityList.js +++ b/scripts/system/html/js/entityList.js @@ -34,22 +34,24 @@ const COMPARE_DESCENDING = function(a, b) { return COMPARE_ASCENDING(b, a); } -var entities = {}; -var entityCount = 0; -// Raw entity data sent from script -let entityData = [] +//console.log = function() { }; + + + +// List of all entities +let entities = [] +// List of all entities, indexed by Entity ID +var entitiesByID = {}; +// The filtered and sorted list of entities +var visibleEntities = []; + var selectedEntities = []; var currentSortColumn = 'type'; var currentSortOrder = ASCENDING_SORT; -var refreshEntityListTimer = null; - -log = function(msg) { - EventBridge.emitWebEvent(msg); -} +const ENABLE_PROFILING = true; var profileIndent = ''; -PROFILE = function(name, fn, args) { - log("PROFILE-Web " + profileIndent + "(" + name + ") Begin"); +const PROFILE = !ENABLE_PROFILING ? function() { } : function(name, fn, args) { console.log("PROFILE-Web " + profileIndent + "(" + name + ") Begin"); var previousIndent = profileIndent; profileIndent += ' '; @@ -57,9 +59,8 @@ PROFILE = function(name, fn, args) { fn.apply(this, args); var delta = Date.now() - before; profileIndent = previousIndent; - log("PROFILE-Web " + profileIndent + "(" + name + ") End " + delta + "ms"); console.log("PROFILE-Web " + profileIndent + "(" + name + ") End " + delta + "ms"); -} +}; debugPrint = function (message) { console.log(message); @@ -127,10 +128,9 @@ function loaded() { function onRowClicked(clickEvent) { let entityID = this.dataset.entityID; console.log("CLICKED", entityID, this); - //return; - var selection = [entityID]; + let selection = [entityID]; if (clickEvent.ctrlKey) { - var selectedIndex = selectedEntities.indexOf(entityID); + let selectedIndex = selectedEntities.indexOf(entityID); if (selectedIndex >= 0) { selection = selectedEntities; selection.splice(selectedIndex, 1) @@ -138,22 +138,23 @@ function loaded() { selection = selection.concat(selectedEntities); } } else if (clickEvent.shiftKey && selectedEntities.length > 0) { - var previousItemFound = -1; - var clickedItemFound = -1; - for (var entity in entityList.visibleItems) { - if (clickedItemFound === -1 && entityID == entityList.visibleItems[entity].values().id) { - clickedItemFound = entity; - } else if(previousItemFound === -1 && selectedEntities[0] == entityList.visibleItems[entity].values().id) { - previousItemFound = entity; + let previousItemFound = -1; + let clickedItemFound = -1; + for (let i = 0, len = visibleEntities.length; i < len; ++i) { + let entity = visibleEntities[i]; + if (clickedItemFound === -1 && entityID == entity.id) { + clickedItemFound = i; + } else if (previousItemFound === -1 && selectedEntities[0] === entity.id) { + previousItemFound = i; } - } + }; if (previousItemFound !== -1 && clickedItemFound !== -1) { - var betweenItems = []; - var toItem = Math.max(previousItemFound, clickedItemFound); + let betweenItems = []; + let toItem = Math.max(previousItemFound, clickedItemFound); // skip first and last item in this loop, we add them to selection after the loop - for (var i = (Math.min(previousItemFound, clickedItemFound) + 1); i < toItem; i++) { - entityList.visibleItems[i].elm.className = 'selected'; - betweenItems.push(entityList.visibleItems[i].values().id); + for (let i = (Math.min(previousItemFound, clickedItemFound) + 1); i < toItem; i++) { + visibleEntities[i].el.className = 'selected'; + betweenItems.push(visibleEntities[i].id); } if (previousItemFound > clickedItemFound) { // always make sure that we add the items in the right order @@ -165,7 +166,7 @@ function loaded() { selectedEntities.forEach(function(entityID) { if (selection.indexOf(entityID) === -1) { - entities[entityID].el.className = ''; + entitiesByID[entityID].el.className = ''; } }); @@ -205,26 +206,28 @@ function loaded() { return urlParts[urlParts.length - 1]; } - function refreshEntityList() { + elFilter.onkeyup = refreshEntityList; + elFilter.onpaste = refreshEntityList; + elFilter.onchange = refreshEntityList; + + // Update the entity list with the new set of data sent from edit.js + function updateEntityList(entityData) { + console.warn("updating entity list"); const IMAGE_MODEL_NAME = 'default-image-model.fbx'; - PROFILE("sort", function() { - let cmp = currentSortOrder === ASCENDING_SORT ? COMPARE_ASCENDING : COMPARE_DESCENDING; - console.log("Doing sort", currentSortColumn, currentSortOrder); - entityData.sort(cmp); - }); + entities = [] + entitiesByID = {}; + visibleEntities = []; - entities = {}; - - let newEntities; PROFILE("map-data", function() { - newEntities = entityData.map(function(entity) { + entityData.forEach(function(entity) { let type = entity.type; let filename = getFilename(entity.url); if (filename === IMAGE_MODEL_NAME) { type = "Image"; } - return { + + let entityData = { id: entity.id, name: entity.name, type: type, @@ -238,46 +241,83 @@ function loaded() { hasTransparent: entity.hasTransparent ? TRANSPARENCY_GLYPH : null, isBaked: entity.isBaked ? BAKED_GLYPH : null, drawCalls: displayIfNonZero(entity.drawCalls), - hasScript: entity.hasScript ? SCRIPT_GLYPH : null + hasScript: entity.hasScript ? SCRIPT_GLYPH : null, } + + entities.push(entityData); + entitiesByID[entityData.id] = entityData; }); }); - console.log("Adding: " + newEntities.length); + PROFILE("create-rows", function() { + entities.forEach(function(entity) { + let row = document.createElement('tr'); + row.dataset.entityID = entity.id; + row.attributes.title = entity.fullUrl; + function addColumn(cls, text) { + let col = document.createElement('td'); + col.className = cls; + col.innerText = text; + row.append(col); + } + function addColumnHTML(cls, text) { + let col = document.createElement('td'); + col.className = cls; + col.innerHTML = text; + row.append(col); + } + addColumn('type', entity.type); + addColumn('name', entity.name); + addColumn('url', entity.url); + addColumnHTML('locked glyph', entity.locked); + addColumnHTML('visible glyph', entity.visible); + addColumn('verticesCount', entity.verticesCount); + addColumn('texturesCount', entity.texturesCount); + addColumn('texturesSize', entity.texturesSize); + addColumnHTML('hasTransparent glyph', entity.hasTransparent); + addColumnHTML('isBaked glyph', entity.isBaked); + addColumn('drawCalls', entity.drawCalls); + addColumn('hasScript glyph', entity.hasScript); + row.addEventListener('click', onRowClicked); + row.addEventListener('dblclick', onRowDoubleClicked); - elEntityTableBody.innerHTML = ''; - - entities = {}; - - PROFILE("update-dom", function() { - newEntities.forEach(function(entity) { - let row = document.createElement('tr'); - row.dataset.entityID = entity.id; - row.attributes.title = entity.fullUrl; - function addColumn(cls, text) { - let col = document.createElement('td'); - col.className = cls; - col.innerText = text; - row.append(col); - } - addColumn('type', entity.type); - addColumn('name', entity.name); - addColumn('url', entity.url); - addColumn('locked glyph', entity.locked); - addColumn('visible glyph', entity.visible); - addColumn('verticesCount', entity.verticesCount); - addColumn('texturesCount', entity.texturesCount); - addColumn('texturesSize', entity.texturesSize); - addColumn('hasTransparent glyph', entity.hasTransparent); - addColumn('isBaked glyph', entity.isBaked); - addColumn('drawCalls', entity.drawCalls); - addColumn('hasScript glyph', entity.hasScript); - elEntityTableBody.append(row); - row.addEventListener('click', onRowClicked); - row.addEventListener('dblclick', onRowDoubleClicked); - entities[entity.id] = { el: row }; + entity.el = row; + }); }); - + + refreshEntityList(); + updateSelectedEntities(selectedEntities); + } + + function refreshEntityList() { + PROFILE("refresh-entity-list", function() { + console.warn("refreshing entity list"); + PROFILE("filter", function() { + let searchTerm = elFilter.value; + if (searchTerm === '') { + visibleEntities = entities.slice(0); + } else { + console.log("Filtering on: ", searchTerm); + visibleEntities = entities.filter(function(e) { + return e.name.indexOf(searchTerm) > -1 + || e.type.indexOf(searchTerm) > -1 + || e.fullUrl.indexOf(searchTerm) > -1; + }); + } + }); + + PROFILE("sort", function() { + let cmp = currentSortOrder === ASCENDING_SORT ? COMPARE_ASCENDING : COMPARE_DESCENDING; + console.log("Doing sort", currentSortColumn, currentSortOrder); + visibleEntities.sort(cmp); + }); + + PROFILE("update-dom", function() { + elEntityTableBody.innerHTML = ''; + for (let i = 0, len = visibleEntities.length; i < len; ++i) { + elEntityTableBody.append(visibleEntities[i].el); + } + }); }); } @@ -290,14 +330,6 @@ function loaded() { } } - function scheduleRefreshEntityList() { - var REFRESH_DELAY = 50; - if (refreshEntityListTimer) { - clearTimeout(refreshEntityListTimer); - } - refreshEntityListTimer = setTimeout(refreshEntityListObject, REFRESH_DELAY); - } - function clearEntities() { entities = {}; refreshFooter(); @@ -327,8 +359,6 @@ function loaded() { currentSortOrder = ASCENDING_SORT; } elSortOrder[column].innerHTML = currentSortOrder == ASCENDING_SORT ? ASCENDING_STRING : DESCENDING_STRING; - - //entityList.sort(currentSortColumn, { order: currentSortOrder }); refreshEntityList(); }); } @@ -340,37 +370,31 @@ function loaded() { } function refreshFooter() { - return; if (selectedEntities.length > 1) { elFooter.firstChild.nodeValue = selectedEntities.length + " entities selected"; } else if (selectedEntities.length === 1) { elFooter.firstChild.nodeValue = "1 entity selected"; - } else if (entityCount === 1) { + } else if (visibleEntities.length === 1) { elFooter.firstChild.nodeValue = "1 entity found"; } else { - elFooter.firstChild.nodeValue = entityCount + " entities found"; + elFooter.firstChild.nodeValue = visibleEntities.length + " entities found"; } } - function refreshEntityListObject() { - refreshEntityListTimer = null; - //entityList.sort(currentSortColumn, { order: currentSortOrder }); - //entityList.search(elFilter.value); - refreshFooter(); - } function updateSelectedEntities(selectedIDs) { - var notFound = false; - for (var id in entities) { - entities[id].el.className = ''; - } + let notFound = false; + + selectedEntities.forEach(function(id) { + entitiesByID[id].el.className = ''; + }); selectedEntities = []; - for (var i = 0; i < selectedIDs.length; i++) { - var id = selectedIDs[i]; + for (let i = 0; i < selectedIDs.length; i++) { + let id = selectedIDs[i]; selectedEntities.push(id); - if (id in entities) { - var entity = entities[id]; + if (id in entitiesByID) { + let entity = entitiesByID[id]; entity.el.className = 'selected'; } else { notFound = true; @@ -461,17 +485,16 @@ function loaded() { elFooter.firstChild.nodeValue = "0 entities found"; } else if (newEntities) { elNoEntitiesMessage.style.display = "none"; - entityData = newEntities; - refreshEntityList(); - //updateSelectedEntities(data.selectedIDs); - //scheduleRefreshEntityList(); + //entityData = newEntities; + updateEntityList(newEntities); + //refreshEntityList(); + updateSelectedEntities(data.selectedIDs); //resize(); } }); } else if (data.type === "removeEntities" && data.deletedIDs !== undefined && data.selectedIDs !== undefined) { removeEntities(data.deletedIDs); updateSelectedEntities(data.selectedIDs); - scheduleRefreshEntityList(); } else if (data.type === "deleted" && data.ids) { removeEntities(data.ids); refreshFooter(); From 1feaf286b43e27f5d077946232a449fa56c96f37 Mon Sep 17 00:00:00 2001 From: sam gateau Date: Wed, 5 Sep 2018 14:35:50 -0700 Subject: [PATCH 266/545] keeping position separated from the other attributes --- libraries/fbx/src/FBXReader_Mesh.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index ef2fcc23b4..bb95fb42f7 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -763,8 +763,8 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { bool interleaveNormalsTangents = true; // If has blend shapes allocate and assign buffers for pos and tangents now + hasBlendShapes = true; if (hasBlendShapes) { - auto posBuffer = std::make_shared(); posBuffer->setData(positionsSize, (const gpu::Byte*) vertBuffer->getData() + positionsOffset); vertexBufferStream->addBuffer(posBuffer, 0, positionElement.getSize()); @@ -781,6 +781,19 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { attribChannel = 2; totalAttribBufferSize = totalVertsSize - positionsSize - normalsAndTangentsSize; + } else { + auto posBuffer = std::make_shared(); + posBuffer->setData(positionsSize, (const gpu::Byte*) vertBuffer->getData() + positionsOffset); + vertexBufferStream->addBuffer(posBuffer, 0, positionElement.getSize()); + + // update channels and attribBuffer size accordingly + interleavePositions = false; + interleaveNormalsTangents = true; + + tangentChannel = 1; + attribChannel = 1; + + totalAttribBufferSize = totalVertsSize - positionsSize; } // Define the vertex format, compute the offset for each attributes as we append them to the vertex format From dcf2e00bd7b38482fde9d69bf41d42ccfc72fd1f Mon Sep 17 00:00:00 2001 From: Alexia Mandeville Date: Wed, 5 Sep 2018 14:55:12 -0700 Subject: [PATCH 267/545] Adding placeholder text --- interface/resources/qml/LoginDialog/LinkAccountBody.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index 4c6e5f6fce..55d157fdd8 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -124,6 +124,7 @@ Item { width: parent.width focus: true label: "Username or Email" + placeholderText: "Username or Email" activeFocusOnPress: true ShortcutText { @@ -151,8 +152,8 @@ Item { TextField { id: passwordField width: parent.width - label: "Password" + placeholderText: "Password" echoMode: showPassword.checked ? TextInput.Normal : TextInput.Password activeFocusOnPress: true From 398724de73698da6dc8c7cbea0acae317f60a625 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 6 Sep 2018 10:23:45 +1200 Subject: [PATCH 268/545] Make Save in HMD settings dialogs return to previous dialog Same as Cancel key does. --- .../hifi/tablet/tabletWindows/TabletPreferencesDialog.qml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/interface/resources/qml/hifi/tablet/tabletWindows/TabletPreferencesDialog.qml b/interface/resources/qml/hifi/tablet/tabletWindows/TabletPreferencesDialog.qml index 31d246be2d..5a0dc24dbc 100644 --- a/interface/resources/qml/hifi/tablet/tabletWindows/TabletPreferencesDialog.qml +++ b/interface/resources/qml/hifi/tablet/tabletWindows/TabletPreferencesDialog.qml @@ -41,7 +41,11 @@ Item { section.saveAll(); } - closeDialog(); + if (HMD.active) { + tablet.popFromStack(); + } else { + closeDialog(); + } } function restoreAll() { From b022697dfa245bcaadaf31c169b4d071d1e5fd17 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Wed, 5 Sep 2018 15:36:07 -0700 Subject: [PATCH 269/545] volume slider on users fixed --- interface/resources/qml/hifi/NameCard.qml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/interface/resources/qml/hifi/NameCard.qml b/interface/resources/qml/hifi/NameCard.qml index abcceae295..dfa6555150 100644 --- a/interface/resources/qml/hifi/NameCard.qml +++ b/interface/resources/qml/hifi/NameCard.qml @@ -530,9 +530,7 @@ Item { maximumValue: 20.0 stepSize: 5 updateValueWhileDragging: true - Component.onCompleted: { - value = Users.getAvatarGain(uuid); - } + value: Users.getAvatarGain(uuid) onValueChanged: { updateGainFromQML(uuid, value, false); } From 960bf00e1200492920bee9336749514c72339750 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 6 Sep 2018 11:02:24 +1200 Subject: [PATCH 270/545] Modify look of HMD mode Settings dialogs' titles --- .../resources/qml/hifi/tablet/TabletMenu.qml | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/interface/resources/qml/hifi/tablet/TabletMenu.qml b/interface/resources/qml/hifi/tablet/TabletMenu.qml index bfbd2d8813..6540d53fca 100644 --- a/interface/resources/qml/hifi/tablet/TabletMenu.qml +++ b/interface/resources/qml/hifi/tablet/TabletMenu.qml @@ -49,11 +49,11 @@ FocusScope { HiFiGlyphs { id: menuRootIcon - text: hifi.glyphs.backward + text: breadcrumbText.text !== "Menu" ? hifi.glyphs.backward : "" size: 72 anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left - width: breadcrumbText.text === "Menu" ? 15 : 50 + width: breadcrumbText.text === "Menu" ? 32 : 50 visible: breadcrumbText.text !== "Menu" MouseArea { @@ -79,23 +79,10 @@ FocusScope { id: breadcrumbText text: "Menu" size: 26 - color: "#34a2c7" + color: "#e3e3e3" anchors.verticalCenter: parent.verticalCenter anchors.left: menuRootIcon.right anchors.leftMargin: 15 - MouseArea { - anchors.fill: parent - hoverEnabled: true - onEntered: breadcrumbText.color = "#1fc6a6"; - onExited: breadcrumbText.color = "#34a2c7"; - // navigate back to parent level menu if there is one - onClicked: { - if (breadcrumbText.text !== "Menu") { - menuPopperUpper.closeLastMenu(); - } - tabletRoot.playButtonClickSound(); - } - } } } From a7099025dcfee39fd8ccd4603e93390dc9f074d8 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 6 Sep 2018 11:15:14 +1200 Subject: [PATCH 271/545] Fix up some Settings dialogs' titles --- interface/resources/qml/hifi/audio/Audio.qml | 2 +- interface/resources/qml/hifi/tablet/ControllerSettings.qml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/interface/resources/qml/hifi/audio/Audio.qml b/interface/resources/qml/hifi/audio/Audio.qml index cc1ba49984..f4a708567a 100644 --- a/interface/resources/qml/hifi/audio/Audio.qml +++ b/interface/resources/qml/hifi/audio/Audio.qml @@ -26,7 +26,7 @@ Rectangle { HifiConstants { id: hifi; } property var eventBridge; - property string title: "Audio Settings - " + AudioScriptingInterface.context; + property string title: "Audio Settings" signal sendToScript(var message); color: hifi.colors.baseGray; diff --git a/interface/resources/qml/hifi/tablet/ControllerSettings.qml b/interface/resources/qml/hifi/tablet/ControllerSettings.qml index 135c1379e2..6706830537 100644 --- a/interface/resources/qml/hifi/tablet/ControllerSettings.qml +++ b/interface/resources/qml/hifi/tablet/ControllerSettings.qml @@ -24,6 +24,8 @@ Item { height: parent.height width: parent.width + property string title: "Controls" + HifiConstants { id: hifi } TabBar { From 1e697ad45f139d281012d87d4099d90b80f32625 Mon Sep 17 00:00:00 2001 From: Alexia Mandeville Date: Wed, 5 Sep 2018 16:25:18 -0700 Subject: [PATCH 272/545] Removing labels, adding flavor text, moving links --- .../qml/LoginDialog/LinkAccountBody.qml | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index 55d157fdd8..f6ad5385c0 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -87,6 +87,21 @@ Item { height: 48 } + FlavorText { + id: flavorTextContainer + anchors { + top: parent.top + margins: 0 + topMargin: hifi.dimensions.contentSpacing.y + } + + text: qsTr("Sign in to High Fidelity to make friends, get HFC, and buy interesting things on the Marketplace!") + wrapMode: Text.WordWrap + lineHeight: 2 + lineHeightMode: Text.ProportionalHeight + horizontalAlignment: Text.AlignHCenter + } + ShortcutText { id: mainTextContainer anchors { @@ -97,7 +112,6 @@ Item { } visible: false - text: qsTr("Username or password incorrect.") wrapMode: Text.WordWrap color: hifi.colors.redAccent @@ -123,15 +137,14 @@ Item { text: Settings.getValue("wallet/savedUsername", ""); width: parent.width focus: true - label: "Username or Email" placeholderText: "Username or Email" activeFocusOnPress: true ShortcutText { z: 10 anchors { - left: usernameField.left - top: usernameField.top + left: usernameField.right + top: usernameField.bottom leftMargin: usernameField.textFieldLabel.contentWidth + 10 topMargin: -19 } @@ -152,7 +165,6 @@ Item { TextField { id: passwordField width: parent.width - label: "Password" placeholderText: "Password" echoMode: showPassword.checked ? TextInput.Normal : TextInput.Password activeFocusOnPress: true @@ -160,8 +172,8 @@ Item { ShortcutText { z: 10 anchors { - left: passwordField.left - top: passwordField.top + left: passwordField.right + top: passwordField.bottom leftMargin: passwordField.textFieldLabel.contentWidth + 10 topMargin: -19 } From bb8d9c5cf0a18845b4ffcdfe3d03eb30382327ae Mon Sep 17 00:00:00 2001 From: Roxanne Skelly Date: Wed, 5 Sep 2018 16:50:08 -0700 Subject: [PATCH 273/545] For stories, base the notification popups off of the action_string instead of a hard-coded value. --- scripts/system/tablet-goto.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/tablet-goto.js b/scripts/system/tablet-goto.js index 46ddeb2bab..80b4e67c43 100644 --- a/scripts/system/tablet-goto.js +++ b/scripts/system/tablet-goto.js @@ -127,7 +127,7 @@ return; } stories[story.id] = story; - var message = story.username + " says something is happening in " + story.place_name + ". Open GOTO to join them."; + var message = story.username + " " + story.action_string + " " + story.place_name + ". Open GOTO to join them."; Window.displayAnnouncement(message); didNotify = true; }); From abb632afda72c9b0d2ee966199e9f2d94726309c Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Wed, 5 Sep 2018 16:51:34 -0700 Subject: [PATCH 274/545] Update capsule when scale/load and teleport without safe landing --- interface/src/avatar/MyAvatar.cpp | 19 +++- interface/src/avatar/MyAvatar.h | 10 +- .../controllers/controllerModules/teleport.js | 100 ++++++++++++++---- 3 files changed, 108 insertions(+), 21 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 640c9821a0..4daa3f5eef 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -113,6 +113,7 @@ MyAvatar::MyAvatar(QThread* thread) : _recentModeReadings(MODE_READINGS_RING_BUFFER_SIZE), _bodySensorMatrix(), _goToPending(false), + _goToSafe(true), _goToPosition(), _goToOrientation(), _prevShouldDrawHead(true), @@ -509,7 +510,9 @@ void MyAvatar::update(float deltaTime) { if (_physicsSafetyPending && qApp->isPhysicsEnabled() && _characterController.isEnabledAndReady()) { // When needed and ready, arrange to check and fix. _physicsSafetyPending = false; - safeLanding(_goToPosition); // no-op if already safe + if (_goToSafe) { + safeLanding(_goToPosition); // no-op if already safe + } } Head* head = getHead(); @@ -3007,7 +3010,7 @@ void MyAvatar::goToFeetLocation(const glm::vec3& newPosition, void MyAvatar::goToLocation(const glm::vec3& newPosition, bool hasOrientation, const glm::quat& newOrientation, - bool shouldFaceLocation) { + bool shouldFaceLocation, bool withSafeLanding) { // Most cases of going to a place or user go through this now. Some possible improvements to think about in the future: // - It would be nice if this used the same teleport steps and smoothing as in the teleport.js script, as long as it @@ -3027,6 +3030,7 @@ void MyAvatar::goToLocation(const glm::vec3& newPosition, _goToPending = true; _goToPosition = newPosition; + _goToSafe = withSafeLanding; _goToOrientation = getWorldOrientation(); if (hasOrientation) { qCDebug(interfaceapp).nospace() << "MyAvatar goToLocation - new orientation is " @@ -3299,6 +3303,17 @@ bool MyAvatar::getCollisionsEnabled() { return _characterController.computeCollisionGroup() != BULLET_COLLISION_GROUP_COLLISIONLESS; } +QVariantMap MyAvatar::getCollisionCapsule() { + glm::vec3 start, end; + float radius; + getCapsule(start, end, radius); + QVariantMap capsule; + capsule["start"] = vec3toVariant(start); + capsule["end"] = vec3toVariant(end); + capsule["radius"] = QVariant(radius); + return capsule; +} + void MyAvatar::setCharacterControllerEnabled(bool enabled) { qCDebug(interfaceapp) << "MyAvatar.characterControllerEnabled is deprecated. Use MyAvatar.collisionsEnabled instead."; setCollisionsEnabled(enabled); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 8121b99e55..0f7ecedcad 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -1017,6 +1017,12 @@ public: */ Q_INVOKABLE bool getCollisionsEnabled(); + /**jsdoc + * @function MyAvatar.getCollisionCapsule + * @returns {object} + */ + Q_INVOKABLE QVariantMap getCollisionCapsule(); + /**jsdoc * @function MyAvatar.setCharacterControllerEnabled * @param {boolean} enabled @@ -1178,11 +1184,12 @@ public slots: * @param {boolean} [hasOrientation=false] - Set to true to set the orientation of the avatar. * @param {Quat} [orientation=Quat.IDENTITY] - The new orientation for the avatar. * @param {boolean} [shouldFaceLocation=false] - Set to true to position the avatar a short distance away from + * @param {boolean} [withSafeLanding=true] - Set to false MyAvatar::safeLanding will not be called (used when teleporting). * the new position and orientate the avatar to face the position. */ void goToLocation(const glm::vec3& newPosition, bool hasOrientation = false, const glm::quat& newOrientation = glm::quat(), - bool shouldFaceLocation = false); + bool shouldFaceLocation = false, bool withSafeLanding = true); /**jsdoc * @function MyAvatar.goToLocation * @param {object} properties @@ -1720,6 +1727,7 @@ private: bool _goToPending { false }; bool _physicsSafetyPending { false }; + bool _goToSafe { true }; glm::vec3 _goToPosition; glm::quat _goToOrientation; diff --git a/scripts/system/controllers/controllerModules/teleport.js b/scripts/system/controllers/controllerModules/teleport.js index c69382a47a..2dea25fc78 100644 --- a/scripts/system/controllers/controllerModules/teleport.js +++ b/scripts/system/controllers/controllerModules/teleport.js @@ -136,9 +136,7 @@ Script.include("/~/system/libraries/controllers.js"); this.state = TELEPORTER_STATES.IDLE; this.currentTarget = TARGET.INVALID; this.currentResult = null; - this.capsuleHeight = 2.0; - this.capsuleRadius = 0.25; - this.pickHeightOffset = 0.01; + this.capsuleThreshold = 0.05; this.getOtherModule = function() { var otherModule = this.hand === RIGHT_HAND ? leftTeleporter : rightTeleporter; @@ -176,18 +174,38 @@ Script.include("/~/system/libraries/controllers.js"); maxDistance: 8.0 }); - this.teleportCollisionPick = Picks.createPick(PickType.Collision, { - enabled: true, - filter: Picks.PICK_ENTITIES + Picks.PICK_AVATARS, - shape: { - shapeType: "capsule-y", - dimensions: { x: _this.capsuleRadius * 2.0, y: _this.capsuleHeight - (_this.capsuleRadius * 2.0), z: _this.capsuleRadius * 2.0 } - }, - position: { x: 0, y: _this.pickHeightOffset + (_this.capsuleHeight * 0.5), z: 0 }, - parentID: Pointers.getPointerProperties(_this.teleportParabolaHandInvisible).renderStates["invisible"].end, - threshold: 0.05 - }); - + this.teleportCollisionPick; + + this.recreateCollisionPick = function() { + if (_this.teleportCollisionPick !== undefined) { + Picks.removePick(_this.teleportCollisionPick); + } + + var capsuleData = MyAvatar.getCollisionCapsule(); + var capsuleHeight = Vec3.distance(capsuleData.start, capsuleData.end); + var offset = Vec3.distance(Vec3.sum(capsuleData.start, {x: 0, y: 0.5*capsuleHeight, z: 0}), MyAvatar.position); + var radius = capsuleData.radius; + var height = 2.0 * radius + capsuleHeight; + + _this.teleportCollisionPick = Picks.createPick(PickType.Collision, { + enabled: true, + parentID: Pointers.getPointerProperties(_this.teleportParabolaHandInvisible).renderStates["invisible"].end, + filter: Picks.PICK_ENTITIES + Picks.PICK_AVATARS, + shape: { + shapeType: "capsule-y", + dimensions: { + x: radius * 2.0, + y: height - (radius * 2.0), + z: radius * 2.0 + } + }, + position: { x: 0, y: offset + (height * 0.5), z: 0 }, + threshold: _this.capsuleThreshold + }); + } + + _this.recreateCollisionPick(); + this.teleportParabolaHeadVisible = Pointers.createPointer(PickType.Parabola, { joint: "Avatar", filter: Picks.PICK_ENTITIES, @@ -222,8 +240,6 @@ Script.include("/~/system/libraries/controllers.js"); Pointers.removePointer(_this.teleportParabolaHeadInvisible); Picks.removePick(_this.teleportCollisionPick); }; - - // Picks.setIgnoreItems(_this.teleportCollisionPick, []); this.axisButtonStateX = 0; // Left/right axis button pressed. this.axisButtonStateY = 0; // Up/down axis button pressed. @@ -355,7 +371,7 @@ Script.include("/~/system/libraries/controllers.js"); } else if (target === TARGET.SURFACE) { var offset = getAvatarFootOffset(); result.intersection.y += offset; - MyAvatar.goToLocation(result.intersection, true, HMD.orientation, false); + MyAvatar.goToLocation(result.intersection, true, HMD.orientation, false, false); HMD.centerUI(); MyAvatar.centerBody(); } @@ -558,7 +574,55 @@ Script.include("/~/system/libraries/controllers.js"); } } }; + + // This class execute a function after the param value haven't been set for a certain time + // It's used in this case to recreate the collision picks once when the avatar scale process ends + + var AfterSet = function(time, maxsteps, callback) { + var self = this; + this.time = time; + this.callback = callback; + this.init = false; + this.value = 0; + this.interval; + this.maxsteps = maxsteps; + this.steps = 0; + this.restateValue = function(value) { + if (self.steps++ > self.maxsteps) { + self.callback.call(this, self.value); + self.steps = 0; + } + if (!self.init) { + console.log("Starting apply after"); + } + self.init = true; + self.value = value; + if (self.interval !== undefined) { + Script.clearInterval(self.interval); + } + self.interval = Script.setInterval(function() { + self.callback.call(this, self.value); + self.init = false; + Script.clearInterval(self.interval); + self.interval = undefined; + }, self.time); + } + } + + var afterSet = new AfterSet(100, 30, function(value) { + leftTeleporter.recreateCollisionPick(); + rightTeleporter.recreateCollisionPick(); + }); + MyAvatar.onLoadComplete.connect(function () { + leftTeleporter.recreateCollisionPick(); + rightTeleporter.recreateCollisionPick(); + }); + + MyAvatar.sensorToWorldScaleChanged.connect(function() { + afterSet.restateValue(MyAvatar.getSensorToWorldScale()); + }); + Messages.subscribe('Hifi-Teleport-Disabler'); Messages.subscribe('Hifi-Teleport-Ignore-Add'); Messages.subscribe('Hifi-Teleport-Ignore-Remove'); From cde2dc2eaa4ffe696c80682b632617527eb1fd5c Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Wed, 5 Sep 2018 17:04:05 -0700 Subject: [PATCH 275/545] please work --- libraries/render-utils/src/CauterizedModel.cpp | 4 ++-- libraries/render-utils/src/CauterizedModel.h | 2 +- libraries/render-utils/src/Model.cpp | 11 +++++++---- libraries/render-utils/src/Model.h | 7 +++++-- libraries/render-utils/src/SoftAttachmentModel.cpp | 4 ++-- libraries/render-utils/src/SoftAttachmentModel.h | 2 +- 6 files changed, 18 insertions(+), 12 deletions(-) diff --git a/libraries/render-utils/src/CauterizedModel.cpp b/libraries/render-utils/src/CauterizedModel.cpp index 2754697db7..c4631c3676 100644 --- a/libraries/render-utils/src/CauterizedModel.cpp +++ b/libraries/render-utils/src/CauterizedModel.cpp @@ -102,7 +102,7 @@ void CauterizedModel::createRenderItemSet() { } } -void CauterizedModel::updateClusterMatrices(bool triggerBlendshapes) { +void CauterizedModel::updateClusterMatrices() { PerformanceTimer perfTimer("CauterizedModel::updateClusterMatrices"); if (!_needsUpdateClusterMatrices || !isLoaded()) { @@ -175,7 +175,7 @@ void CauterizedModel::updateClusterMatrices(bool triggerBlendshapes) { // post the blender if we're not currently waiting for one to finish auto modelBlender = DependencyManager::get(); - if (triggerBlendshapes && modelBlender->shouldComputeBlendshapes() && geometry.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) { + if (_blendedVertexBuffersInitialized && modelBlender->shouldComputeBlendshapes() && geometry.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) { _blendedBlendshapeCoefficients = _blendshapeCoefficients; modelBlender->noteRequiresBlend(getThisPointer()); } diff --git a/libraries/render-utils/src/CauterizedModel.h b/libraries/render-utils/src/CauterizedModel.h index 12cf921e5b..36a96fb006 100644 --- a/libraries/render-utils/src/CauterizedModel.h +++ b/libraries/render-utils/src/CauterizedModel.h @@ -33,7 +33,7 @@ public: void createRenderItemSet() override; - virtual void updateClusterMatrices(bool triggerBlendshapes = true) override; + virtual void updateClusterMatrices() override; void updateRenderItems() override; const Model::MeshState& getCauterizeMeshState(int index) const; diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 8287b9cca6..ba2bd28852 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -976,7 +976,7 @@ bool Model::addToScene(const render::ScenePointer& scene, render::Transaction& transaction, render::Item::Status::Getters& statusGetters) { if (!_addedToScene && isLoaded()) { - updateClusterMatrices(false); + updateClusterMatrices(); if (_modelMeshRenderItems.empty()) { createRenderItemSet(); } @@ -1307,6 +1307,7 @@ void Blender::run() { if (mesh.blendshapes.isEmpty()) { continue; } + vertices += mesh.vertices; normalsAndTangents += mesh.normalsAndTangents; glm::vec3* meshVertices = vertices.data() + offset; @@ -1486,7 +1487,7 @@ void Model::computeMeshPartLocalBounds() { } // virtual -void Model::updateClusterMatrices(bool triggerBlendshapes) { +void Model::updateClusterMatrices() { DETAILED_PERFORMANCE_TIMER("Model::updateClusterMatrices"); if (!_needsUpdateClusterMatrices || !isLoaded()) { @@ -1515,7 +1516,7 @@ void Model::updateClusterMatrices(bool triggerBlendshapes) { // post the blender if we're not currently waiting for one to finish auto modelBlender = DependencyManager::get(); - if (triggerBlendshapes && modelBlender->shouldComputeBlendshapes() && geometry.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) { + if (_blendedVertexBuffersInitialized && modelBlender->shouldComputeBlendshapes() && geometry.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) { _blendedBlendshapeCoefficients = _blendshapeCoefficients; modelBlender->noteRequiresBlend(getThisPointer()); } @@ -1552,7 +1553,7 @@ void Model::setBlendedVertices(int blendNumber, const Geometry::WeakPointer& geo const auto vertexCount = mesh.vertices.size(); const auto verticesSize = vertexCount * sizeof(glm::vec3); const auto& buffer = _blendedVertexBuffers[i]; - assert(buffer); + assert(buffer && _blendedVertexBuffersInitialized); buffer->resize(mesh.vertices.size() * sizeof(glm::vec3) + mesh.normalsAndTangents.size() * sizeof(NormalType)); buffer->setSubData(0, verticesSize, (gpu::Byte*) vertices.constData() + index * sizeof(glm::vec3)); buffer->setSubData(verticesSize, mesh.normalsAndTangents.size() * sizeof(NormalType), (const gpu::Byte*) normalsAndTangents.data() + normalAndTangentIndex * sizeof(NormalType)); @@ -1565,6 +1566,7 @@ void Model::setBlendedVertices(int blendNumber, const Geometry::WeakPointer& geo void Model::deleteGeometry() { _deleteGeometryCounter++; _blendedVertexBuffers.clear(); + _blendedVertexBuffersInitialized = false; _meshStates.clear(); _rig.destroyAnimGraph(); _blendedBlendshapeCoefficients.clear(); @@ -1630,6 +1632,7 @@ void Model::initializeBlendshapes(const FBXMesh& mesh, int index) { _blendedVertexBuffers[index]->setSubData(0, verticesSize, (const gpu::Byte*) mesh.vertices.constData()); _blendedVertexBuffers[index]->setSubData(verticesSize, normalsAndTangents.size() * sizeof(NormalType), (const gpu::Byte*) normalsAndTangents.data()); mesh.normalsAndTangents = normalsAndTangents; + _blendedVertexBuffersInitialized = true; } void Model::createRenderItemSet() { diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 5ab50da162..e7534f5b89 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -159,7 +159,7 @@ public: bool getSnapModelToRegistrationPoint() { return _snapModelToRegistrationPoint; } virtual void simulate(float deltaTime, bool fullUpdate = true); - virtual void updateClusterMatrices(bool triggerBlendshapes = true); + virtual void updateClusterMatrices(); /// Returns a reference to the shared geometry. const Geometry::Pointer& getGeometry() const { return _renderGeometry; } @@ -345,6 +345,8 @@ public: void addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName); void removeMaterial(graphics::MaterialPointer material, const std::string& parentMaterialName); + bool areBlendedVertexBuffersInitialized(int index) { return _blendedVertexBuffersInitialized; } + public slots: void loadURLFinished(bool success); @@ -424,8 +426,9 @@ protected: QUrl _url; std::unordered_map _blendedVertexBuffers; + bool _blendedVertexBuffersInitialized { false }; - QVector > > _dilatedTextures; + QVector>> _dilatedTextures; QVector _blendedBlendshapeCoefficients; int _blendNumber; diff --git a/libraries/render-utils/src/SoftAttachmentModel.cpp b/libraries/render-utils/src/SoftAttachmentModel.cpp index 93ce8f595a..b9a6581f1d 100644 --- a/libraries/render-utils/src/SoftAttachmentModel.cpp +++ b/libraries/render-utils/src/SoftAttachmentModel.cpp @@ -31,7 +31,7 @@ int SoftAttachmentModel::getJointIndexOverride(int i) const { // virtual // use the _rigOverride matrices instead of the Model::_rig -void SoftAttachmentModel::updateClusterMatrices(bool triggerBlendshapes) { +void SoftAttachmentModel::updateClusterMatrices() { if (!_needsUpdateClusterMatrices) { return; } @@ -78,7 +78,7 @@ void SoftAttachmentModel::updateClusterMatrices(bool triggerBlendshapes) { // post the blender if we're not currently waiting for one to finish auto modelBlender = DependencyManager::get(); - if (triggerBlendshapes && modelBlender->shouldComputeBlendshapes() && geometry.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) { + if (_blendedVertexBuffersInitialized && modelBlender->shouldComputeBlendshapes() && geometry.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) { _blendedBlendshapeCoefficients = _blendshapeCoefficients; modelBlender->noteRequiresBlend(getThisPointer()); } diff --git a/libraries/render-utils/src/SoftAttachmentModel.h b/libraries/render-utils/src/SoftAttachmentModel.h index 03038c35f3..4335c1634e 100644 --- a/libraries/render-utils/src/SoftAttachmentModel.h +++ b/libraries/render-utils/src/SoftAttachmentModel.h @@ -27,7 +27,7 @@ public: ~SoftAttachmentModel(); void updateRig(float deltaTime, glm::mat4 parentTransform) override; - void updateClusterMatrices(bool triggerBlendshapes = true) override; + void updateClusterMatrices() override; protected: int getJointIndexOverride(int i) const; From 901de120a694fef83871f48b5d07292da50dd88d Mon Sep 17 00:00:00 2001 From: Alexia Mandeville Date: Wed, 5 Sep 2018 17:20:49 -0700 Subject: [PATCH 276/545] Removing flavortext --- .../resources/qml/LoginDialog/LinkAccountBody.qml | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index f6ad5385c0..423f6cc73b 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -86,21 +86,6 @@ Item { width: 48 height: 48 } - - FlavorText { - id: flavorTextContainer - anchors { - top: parent.top - margins: 0 - topMargin: hifi.dimensions.contentSpacing.y - } - - text: qsTr("Sign in to High Fidelity to make friends, get HFC, and buy interesting things on the Marketplace!") - wrapMode: Text.WordWrap - lineHeight: 2 - lineHeightMode: Text.ProportionalHeight - horizontalAlignment: Text.AlignHCenter - } ShortcutText { id: mainTextContainer From d2650f7ede3cfafa2130d51016b30412d1c10f29 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 5 Sep 2018 17:22:07 -0700 Subject: [PATCH 277/545] Modified priority function from Andrew --- .../src/avatars/AvatarMixerSlave.cpp | 6 +- libraries/shared/src/PrioritySortUtil.h | 64 +++---------------- 2 files changed, 11 insertions(+), 59 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index a61f65ffb0..9e38f465d3 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -313,9 +313,9 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // prepare to sort const auto& cameraViews = nodeData->getViewFrustums(); PrioritySortUtil::PriorityQueue sortedAvatars(cameraViews, - AvatarData::_avatarSortCoefficientSize, - AvatarData::_avatarSortCoefficientCenter, - AvatarData::_avatarSortCoefficientAge); + /*AvatarData::_avatarSortCoefficientSize*/ 1.0f, // Suggested weights from Andrew M. + /*AvatarData::_avatarSortCoefficientCenter*/ 0.5f, + /*AvatarData::_avatarSortCoefficientAge*/ 0.25f); sortedAvatars.reserve(_end - _begin); for (auto listedNode = _begin; listedNode != _end; ++listedNode) { diff --git a/libraries/shared/src/PrioritySortUtil.h b/libraries/shared/src/PrioritySortUtil.h index 0a9bb45d46..ac2e6a6852 100644 --- a/libraries/shared/src/PrioritySortUtil.h +++ b/libraries/shared/src/PrioritySortUtil.h @@ -16,49 +16,7 @@ #include "NumericalConstants.h" #include "shared/ConicalViewFrustum.h" -/* PrioritySortUtil is a helper for sorting 3D things relative to a ViewFrustum. To use: - -(1) Derive a class from pure-virtual PrioritySortUtil::Sortable that wraps a copy of - the Thing you want to prioritize and sort: - - class SortableWrapper: public PrioritySortUtil::Sortable { - public: - SortableWrapper(const Thing& thing) : _thing(thing) { } - glm::vec3 getPosition() const override { return _thing->getPosition(); } - float getRadius() const override { return 0.5f * _thing->getBoundingRadius(); } - uint64_t getTimestamp() const override { return _thing->getLastTime(); } - Thing getThing() const { return _thing; } - private: - Thing _thing; - }; - -(2) Make a PrioritySortUtil::PriorityQueue and add them to the queue: - - PrioritySortUtil::PriorityQueue sortedThings(viewFrustum); - std::priority_queue< PrioritySortUtil::Sortable > sortedThings; - for (thing in things) { - sortedThings.push(SortableWrapper(thing)); - } - -(3) Loop over your priority queue and do timeboxed work: - - NOTE: Be careful using references to members of instances of T from std::priority_queue. - Under the hood std::priority_queue may re-use instances of T. - For example, after a pop() or a push() the top T may have the same memory address - as the top T before the pop() or push() (but point to a swapped instance of T). - This causes a reference to member variable of T to point to a different value - when operations taken on std::priority_queue shuffle around the instances of T. - - uint64_t cutoffTime = usecTimestampNow() + TIME_BUDGET; - while (!sortedThings.empty()) { - const Thing& thing = sortedThings.top(); - // ...do work on thing... - sortedThings.pop(); - if (usecTimestampNow() > cutoffTime) { - break; - } - } -*/ +// PrioritySortUtil is a helper for sorting 3D things relative to a ViewFrustum. namespace PrioritySortUtil { @@ -84,9 +42,9 @@ namespace PrioritySortUtil { PriorityQueue() = delete; PriorityQueue(const ConicalViewFrustums& views) : _views(views) { } PriorityQueue(const ConicalViewFrustums& views, float angularWeight, float centerWeight, float ageWeight) - : _views(views), _angularWeight(angularWeight), _centerWeight(centerWeight), _ageWeight(ageWeight) - , _usecCurrentTime(usecTimestampNow()) - { } + : _views(views), _angularWeight(angularWeight), _centerWeight(centerWeight), _ageWeight(ageWeight) + , _usecCurrentTime(usecTimestampNow()) { + } void setViews(const ConicalViewFrustums& views) { _views = views; } @@ -138,14 +96,9 @@ namespace PrioritySortUtil { float cosineAngle = (glm::dot(offset, view.getDirection()) / distance); float age = (float)(_usecCurrentTime - thing.getTimestamp()); - // we modulate "age" drift rate by the cosineAngle term to make peripheral objects sort forward - // at a reduced rate but we don't want the "age" term to go zero or negative so we clamp it - const float MIN_COSINE_ANGLE_FACTOR = 0.1f; - float cosineAngleFactor = glm::max(cosineAngle, MIN_COSINE_ANGLE_FACTOR); - - float priority = _angularWeight * radius / distance - + _centerWeight * cosineAngle - + _ageWeight * cosineAngleFactor * age; + // the "age" term accumulates at the sum of all weights + float angularSize = glm::max(radius, MIN_RADIUS) / distance; + float priority = (_angularWeight * angularSize + _centerWeight * cosineAngle) * (age + 1.0f) + _ageWeight * age; // decrement priority of things outside keyhole if (distance - radius > view.getRadius()) { @@ -166,9 +119,8 @@ namespace PrioritySortUtil { }; } // namespace PrioritySortUtil -// for now we're keeping hard-coded sorted time budgets in one spot + // for now we're keeping hard-coded sorted time budgets in one spot const uint64_t MAX_UPDATE_RENDERABLES_TIME_BUDGET = 2000; // usec const uint64_t MIN_SORTED_UPDATE_RENDERABLES_TIME_BUDGET = 1000; // usec #endif // hifi_PrioritySortUtil_h - From adf0a9a4147df64c59d325be68a7834aa1cc7493 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 5 Sep 2018 17:41:00 -0700 Subject: [PATCH 278/545] Convert priority age from microseconds to seconds --- libraries/shared/src/PrioritySortUtil.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/shared/src/PrioritySortUtil.h b/libraries/shared/src/PrioritySortUtil.h index ac2e6a6852..075de13d9d 100644 --- a/libraries/shared/src/PrioritySortUtil.h +++ b/libraries/shared/src/PrioritySortUtil.h @@ -22,7 +22,7 @@ namespace PrioritySortUtil { constexpr float DEFAULT_ANGULAR_COEF { 1.0f }; constexpr float DEFAULT_CENTER_COEF { 0.5f }; - constexpr float DEFAULT_AGE_COEF { 0.25f / (float)(USECS_PER_SECOND) }; + constexpr float DEFAULT_AGE_COEF { 0.25f }; class Sortable { public: @@ -94,7 +94,7 @@ namespace PrioritySortUtil { float radius = glm::max(thing.getRadius(), MIN_RADIUS); // Other item's angle from view centre: float cosineAngle = (glm::dot(offset, view.getDirection()) / distance); - float age = (float)(_usecCurrentTime - thing.getTimestamp()); + float age = float((_usecCurrentTime - thing.getTimestamp()) / USECS_PER_SECOND); // the "age" term accumulates at the sum of all weights float angularSize = glm::max(radius, MIN_RADIUS) / distance; From 21f65d8a78d8dbba1608797a9d758bc1f93556f5 Mon Sep 17 00:00:00 2001 From: sam gateau Date: Wed, 5 Sep 2018 17:50:06 -0700 Subject: [PATCH 279/545] position are used correctly for evaluting bounds in the Mesh --- libraries/fbx/src/FBXReader_Mesh.cpp | 4 ++-- libraries/graphics/src/graphics/Geometry.cpp | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index bb95fb42f7..7b83e74ebc 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -781,7 +781,7 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { attribChannel = 2; totalAttribBufferSize = totalVertsSize - positionsSize - normalsAndTangentsSize; - } else { + } /*else { auto posBuffer = std::make_shared(); posBuffer->setData(positionsSize, (const gpu::Byte*) vertBuffer->getData() + positionsOffset); vertexBufferStream->addBuffer(posBuffer, 0, positionElement.getSize()); @@ -794,7 +794,7 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { attribChannel = 1; totalAttribBufferSize = totalVertsSize - positionsSize; - } + }*/ // Define the vertex format, compute the offset for each attributes as we append them to the vertex format gpu::Offset bufOffset = 0; diff --git a/libraries/graphics/src/graphics/Geometry.cpp b/libraries/graphics/src/graphics/Geometry.cpp index 2fbe3708fd..f71dcbe27d 100755 --- a/libraries/graphics/src/graphics/Geometry.cpp +++ b/libraries/graphics/src/graphics/Geometry.cpp @@ -120,7 +120,8 @@ Box Mesh::evalPartBound(int partNum) const { for (;index != endIndex; index++) { // skip primitive restart indices if ((*index) != PRIMITIVE_RESTART_INDEX) { - box += vertices[(*index)]; + // box += vertices[(*index)]; + box += _vertexBuffer.get(part._baseVertex + (*index)); } } } @@ -137,11 +138,12 @@ Box Mesh::evalPartsBound(int partStart, int partEnd) const { Box partBound; auto index = _indexBuffer.cbegin() + (*part)._startIndex; auto endIndex = index + (*part)._numIndices; - auto vertices = &_vertexBuffer.get((*part)._baseVertex); + //auto vertices = &_vertexBuffer.get((*part)._baseVertex); for (;index != endIndex; index++) { // skip primitive restart indices if ((*index) != (uint) PRIMITIVE_RESTART_INDEX) { - partBound += vertices[(*index)]; + //partBound += vertices[(*index)]; + partBound += _vertexBuffer.get((*part)._baseVertex + (*index)); } } From 6fb335429de5b9db88c76d5d825e5d4dfb8530c6 Mon Sep 17 00:00:00 2001 From: amantley Date: Wed, 5 Sep 2018 17:55:27 -0700 Subject: [PATCH 280/545] starting to re-implement the walking state detection for smoothwalking --- interface/src/avatar/MyAvatar.cpp | 15 +++++++++++++-- interface/src/avatar/MyAvatar.h | 1 + 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 4fa41809d0..8a29d3f9c7 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -516,6 +516,10 @@ void MyAvatar::update(float deltaTime) { head->relax(deltaTime); updateFromTrackers(deltaTime); + if (_isInWalkingState && glm::length(getControllerPoseInAvatarFrame(controller::Action::HEAD).getVelocity()) < 0.15f) { + _isInWalkingState = false; + } + // Get audio loudness data from audio input device // Also get the AudioClient so we can update the avatar bounding box data // on the AudioClient side. @@ -3912,7 +3916,7 @@ void MyAvatar::lateUpdatePalms() { Avatar::updatePalms(); } -static const float FOLLOW_TIME = 0.1f; +static const float FOLLOW_TIME = 0.5f; MyAvatar::FollowHelper::FollowHelper() { deactivate(); @@ -4002,7 +4006,8 @@ bool MyAvatar::FollowHelper::shouldActivateHorizontalCG(MyAvatar& myAvatar) cons controller::Pose currentLeftHandPose = myAvatar.getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND); controller::Pose currentRightHandPose = myAvatar.getControllerPoseInAvatarFrame(controller::Action::RIGHT_HAND); - + qCDebug(interfaceapp) << "currentVelocity is " < 0.15f) { + myAvatar._isInWalkingState = true; + } } else { glm::vec3 defaultHipsPosition = myAvatar.getAbsoluteDefaultJointTranslationInObjectFrame(myAvatar.getJointIndex("Hips")); glm::vec3 defaultHeadPosition = myAvatar.getAbsoluteDefaultJointTranslationInObjectFrame(myAvatar.getJointIndex("Head")); @@ -4024,6 +4032,9 @@ bool MyAvatar::FollowHelper::shouldActivateHorizontalCG(MyAvatar& myAvatar) cons myAvatar.setResetMode(true); qCDebug(interfaceapp) << "failsafe called, default back " << anatomicalHeadToHipsDistance << " scale " << myAvatar.getAvatarScale() << " current length " << glm::length(currentHeadPosition - defaultHipsPosition); stepDetected = true; + if (glm::length(currentHeadPose.velocity) > 0.15f) { + myAvatar._isInWalkingState = true; + } } qCDebug(interfaceapp) << "current head height " << currentHeadPose.getTranslation().y << " scale " << myAvatar.getAvatarScale() << " anatomical " << anatomicalHeadToHipsDistance; } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 06267b3819..aa76e29b14 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -1788,6 +1788,7 @@ private: ThreadSafeValueCache _walkBackwardSpeed { DEFAULT_AVATAR_MAX_WALKING_BACKWARD_SPEED }; ThreadSafeValueCache _sprintSpeed { AVATAR_SPRINT_SPEED_SCALAR }; float _walkSpeedScalar { AVATAR_WALK_SPEED_SCALAR }; + bool _isInWalkingState { false }; // load avatar scripts once when rig is ready bool _shouldLoadScripts { false }; From 3a3ffcc98c792736ef7bfa0495606a11e3c99f7d Mon Sep 17 00:00:00 2001 From: Anthony Thibault Date: Wed, 5 Sep 2018 18:14:06 -0700 Subject: [PATCH 281/545] First pass at improving anim stats. --- interface/resources/qml/Stats.qml | 61 ++++++++++-- interface/src/ui/Stats.cpp | 92 ++++++++++++++++++- interface/src/ui/Stats.h | 25 +++-- libraries/animation/src/AnimBlendLinear.cpp | 10 +- .../animation/src/AnimBlendLinearMove.cpp | 18 +--- libraries/animation/src/AnimContext.h | 42 +++++++++ libraries/animation/src/AnimNode.cpp | 4 - libraries/animation/src/AnimNode.h | 18 +--- libraries/animation/src/AnimStateMachine.cpp | 25 +---- libraries/animation/src/AnimStateMachine.h | 1 - libraries/animation/src/AnimVariant.cpp | 41 +++++++++ libraries/animation/src/AnimVariant.h | 3 + libraries/animation/src/Rig.cpp | 2 + libraries/animation/src/Rig.h | 7 +- 14 files changed, 264 insertions(+), 85 deletions(-) diff --git a/interface/resources/qml/Stats.qml b/interface/resources/qml/Stats.qml index d5cfcff1e2..26682d3db8 100644 --- a/interface/resources/qml/Stats.qml +++ b/interface/resources/qml/Stats.qml @@ -193,18 +193,63 @@ Item { text: "Yaw: " + root.yaw.toFixed(1) } StatText { - visible: root.animStackNames.length > 0; - text: "Anim Stack Names:" + visible: root.animAlphaValues.length > 0; + text: "Anim Alpha Values:" } ListView { width: geoCol.width - height: root.animStackNames.length * 15 - visible: root.animStackNames.length > 0; - model: root.animStackNames + height: root.animAlphaValues.length * 15 + visible: root.animAlphaValues.length > 0; + model: root.animAlphaValues delegate: StatText { - text: modelData.length > 30 - ? modelData.substring(0, 5) + "..." + modelData.substring(modelData.length - 22) - : modelData + text: { + var actualText = modelData.split("|")[1]; + if (actualText) { + if (actualText.length > 30) { + return actualText.substring(0, 5) + "..." + actualText.substring(actualText.length - 22); + } else { + return actualText; + } + } else { + return modelData; + } + } + color: { + var grayScale = parseFloat(modelData.split("|")[0]); + return Qt.rgba(0.3 * grayScale + 0.7, + 0.3 * grayScale + 0.7, + 0.3 * grayScale + 0.7, 1.0); + } + } + } + StatText { + visible: root.animVars.length > 0; + text: "AnimVars:" + } + ListView { + width: geoCol.width + height: root.animVars.length * 15 + visible: root.animVars.length > 0; + model: root.animVars + delegate: StatText { + text: { + var actualText = modelData.split("|")[1]; + if (actualText) { + if (actualText.length > 30) { + return actualText.substring(0, 5) + "..." + actualText.substring(actualText.length - 22); + } else { + return actualText; + } + } else { + return modelData; + } + } + color: { + var grayScale = parseFloat(modelData.split("|")[0]); + return Qt.rgba(0.3 * grayScale + 0.7, + 0.3 * grayScale + 0.7, + 0.3 * grayScale + 0.7, 1.0); + } } } StatText { diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index 1b26c9b621..62e44645b9 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -207,13 +207,94 @@ void Stats::updateStats(bool force) { // Third column, avatar stats auto myAvatar = avatarManager->getMyAvatar(); - auto animStack = myAvatar->getSkeletonModel()->getRig().getAnimStack(); + auto debugAlphaMap = myAvatar->getSkeletonModel()->getRig().getDebugAlphaMap(); - _animStackNames.clear(); - for (auto animStackIterator = animStack.begin(); animStackIterator != animStack.end(); ++animStackIterator) { - _animStackNames << animStackIterator->first + ": " + QString::number(animStackIterator->second,'f',3); + // update animation debug alpha values + QStringList newAnimAlphaValues; + qint64 now = usecTimestampNow(); + for (auto& iter : debugAlphaMap) { + QString key = iter.first; + float alpha = std::get<0>(iter.second); + + auto prevIter = _prevDebugAlphaMap.find(key); + if (prevIter != _prevDebugAlphaMap.end()) { + float prevAlpha = std::get<0>(iter.second); + if (prevAlpha != alpha) { + // change detected: reset timer + _animAlphaValueChangedTimers[key] = now; + } + } else { + // new value: start timer + _animAlphaValueChangedTimers[key] = now; + } + + AnimNodeType type = std::get<1>(iter.second); + if (type == AnimNodeType::Clip) { + + // figure out the grayScale color of this line. + const float LIT_TIME = 2.0f; + const float FADE_OUT_TIME = 1.0f; + float grayScale = 0.0f; + float secondsElapsed = (float)(now - _animAlphaValueChangedTimers[key]) / (float)USECS_PER_SECOND; + if (secondsElapsed < LIT_TIME) { + grayScale = 1.0f; + } else if (secondsElapsed < LIT_TIME + FADE_OUT_TIME) { + grayScale = (LIT_TIME - (secondsElapsed - FADE_OUT_TIME)) / LIT_TIME; + } else { + grayScale = 0.0f; + } + + if (grayScale > 0.0f) { + // append grayScaleColor to start of debug string + newAnimAlphaValues << QString::number(grayScale, 'f', 2) + "|" + key + ": " + QString::number(alpha, 'f', 3); + } + } } - emit animStackNamesChanged(); + + _animAlphaValues = newAnimAlphaValues; + _prevDebugAlphaMap = debugAlphaMap; + + emit animAlphaValuesChanged(); + + // update animation anim vars + _animVarsList.clear(); + auto animVars = myAvatar->getSkeletonModel()->getRig().getAnimVars().toDebugMap(); + for (auto& iter : animVars) { + QString key = iter.first; + QString value = iter.second; + + auto prevIter = _prevAnimVars.find(key); + if (prevIter != _prevAnimVars.end()) { + QString prevValue = prevIter->second; + if (value != prevValue) { + // change detected: reset timer + _animVarChangedTimers[key] = now; + } + } else { + // new value: start timer + _animVarChangedTimers[key] = now; + } + + // figure out the grayScale color of this line. + const float LIT_TIME = 2.0f; + const float FADE_OUT_TIME = 0.5f; + float grayScale = 0.0f; + float secondsElapsed = (float)(now - _animVarChangedTimers[key]) / (float)USECS_PER_SECOND; + if (secondsElapsed < LIT_TIME) { + grayScale = 1.0f; + } else if (secondsElapsed < LIT_TIME + FADE_OUT_TIME) { + grayScale = (LIT_TIME - (secondsElapsed - FADE_OUT_TIME)) / LIT_TIME; + } else { + grayScale = 0.0f; + } + + if (grayScale > 0.0f) { + // append grayScaleColor to start of debug string + _animVarsList << QString::number(grayScale, 'f', 2) + "|" + key + ": " + value; + } + } + _prevAnimVars = animVars; + emit animVarsChanged(); glm::vec3 avatarPos = myAvatar->getWorldPosition(); STAT_UPDATE(position, QVector3D(avatarPos.x, avatarPos.y, avatarPos.z)); @@ -347,6 +428,7 @@ void Stats::updateStats(bool force) { } sendingModeStream << "] " << serverCount << " servers"; if (movingServerCount > 0) { + sendingModeStream << " "; } else { sendingModeStream << " "; diff --git a/interface/src/ui/Stats.h b/interface/src/ui/Stats.h index a0453a09c5..3e71c75da1 100644 --- a/interface/src/ui/Stats.h +++ b/interface/src/ui/Stats.h @@ -14,6 +14,7 @@ #include #include #include +#include #define STATS_PROPERTY(type, name, initialValue) \ Q_PROPERTY(type name READ name NOTIFY name##Changed) \ @@ -134,7 +135,6 @@ private: \ * @property {number} batchFrameTime - Read-only. * @property {number} engineFrameTime - Read-only. * @property {number} avatarSimulationTime - Read-only. - * @property {string[]} animStackNames - Read-only. * * * @property {number} x @@ -292,7 +292,8 @@ class Stats : public QQuickItem { STATS_PROPERTY(float, batchFrameTime, 0) STATS_PROPERTY(float, engineFrameTime, 0) STATS_PROPERTY(float, avatarSimulationTime, 0) - Q_PROPERTY(QStringList animStackNames READ animStackNames NOTIFY animStackNamesChanged) + Q_PROPERTY(QStringList animAlphaValues READ animAlphaValues NOTIFY animAlphaValuesChanged) + Q_PROPERTY(QStringList animVars READ animVars NOTIFY animVarsChanged) STATS_PROPERTY(int, stylusPicksCount, 0) STATS_PROPERTY(int, rayPicksCount, 0) @@ -326,7 +327,8 @@ public: } QStringList downloadUrls () { return _downloadUrls; } - QStringList animStackNames() { return _animStackNames; } + QStringList animAlphaValues() { return _animAlphaValues; } + QStringList animVars() { return _animVarsList; } public slots: void forceUpdateStats() { updateStats(true); } @@ -1028,12 +1030,8 @@ signals: */ void avatarSimulationTimeChanged(); - /**jsdoc - * Triggered when the value of the animStackNames property changes. - * @function Stats.animStackNamesChanged - * @returns {Signal} - */ - void animStackNamesChanged(); + void animAlphaValuesChanged(); + void animVarsChanged(); /**jsdoc * Triggered when the value of the rectifiedTextureCount property changes. @@ -1336,7 +1334,14 @@ private: QString _monospaceFont; const AudioIOStats* _audioStats; QStringList _downloadUrls = QStringList(); - QStringList _animStackNames = QStringList(); + + QStringList _animAlphaValues = QStringList(); + AnimContext::DebugAlphaMap _prevDebugAlphaMap; // alpha values from previous frame + std::map _animAlphaValueChangedTimers; // last time alpha value has changed + + QStringList _animVarsList = QStringList(); + std::map _prevAnimVars; // anim vars from previous frame + std::map _animVarChangedTimers; // last time animVar value has changed. }; #endif // hifi_Stats_h diff --git a/libraries/animation/src/AnimBlendLinear.cpp b/libraries/animation/src/AnimBlendLinear.cpp index e2d79f864d..17ca88123f 100644 --- a/libraries/animation/src/AnimBlendLinear.cpp +++ b/libraries/animation/src/AnimBlendLinear.cpp @@ -27,7 +27,7 @@ AnimBlendLinear::~AnimBlendLinear() { const AnimPoseVec& AnimBlendLinear::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) { _alpha = animVars.lookup(_alphaVar, _alpha); - float parentAlpha = _animStack[_id]; + float parentDebugAlpha = context.getDebugAlpha(_id); if (_children.size() == 0) { for (auto&& pose : _poses) { @@ -35,7 +35,7 @@ const AnimPoseVec& AnimBlendLinear::evaluate(const AnimVariantMap& animVars, con } } else if (_children.size() == 1) { _poses = _children[0]->evaluate(animVars, context, dt, triggersOut); - _animStack[_children[0]->getID()] = parentAlpha; + context.setDebugAlpha(_children[0]->getID(), parentDebugAlpha, _children[0]->getType()); } else { float clampedAlpha = glm::clamp(_alpha, 0.0f, (float)(_children.size() - 1)); size_t prevPoseIndex = glm::floor(clampedAlpha); @@ -48,12 +48,12 @@ const AnimPoseVec& AnimBlendLinear::evaluate(const AnimVariantMap& animVars, con float weight2 = 0.0f; if (prevPoseIndex == nextPoseIndex) { weight2 = 1.0f; - _animStack[_children[nextPoseIndex]->getID()] = weight2 * parentAlpha; + context.setDebugAlpha(_children[nextPoseIndex]->getID(), weight2 * parentDebugAlpha, _children[nextPoseIndex]->getType()); } else { weight2 = alpha; weight1 = 1.0f - weight2; - _animStack[_children[prevPoseIndex]->getID()] = weight1 * parentAlpha; - _animStack[_children[nextPoseIndex]->getID()] = weight2 * parentAlpha; + context.setDebugAlpha(_children[prevPoseIndex]->getID(), weight1 * parentDebugAlpha, _children[prevPoseIndex]->getType()); + context.setDebugAlpha(_children[nextPoseIndex]->getID(), weight2 * parentDebugAlpha, _children[nextPoseIndex]->getType()); } } processOutputJoints(triggersOut); diff --git a/libraries/animation/src/AnimBlendLinearMove.cpp b/libraries/animation/src/AnimBlendLinearMove.cpp index 42098eb072..07e1c17f77 100644 --- a/libraries/animation/src/AnimBlendLinearMove.cpp +++ b/libraries/animation/src/AnimBlendLinearMove.cpp @@ -62,9 +62,7 @@ const AnimPoseVec& AnimBlendLinearMove::evaluate(const AnimVariantMap& animVars, speed = animVars.lookup("moveForwardSpeed", speed); } _alpha = calculateAlpha(speed, _characteristicSpeeds); - float parentAlpha = _animStack[_id]; - - _animStack["speed"] = speed; + float parentDebugAlpha = context.getDebugAlpha(_id); if (_children.size() == 0) { for (auto&& pose : _poses) { @@ -77,7 +75,7 @@ const AnimPoseVec& AnimBlendLinearMove::evaluate(const AnimVariantMap& animVars, float prevDeltaTime, nextDeltaTime; setFrameAndPhase(dt, alpha, prevPoseIndex, nextPoseIndex, &prevDeltaTime, &nextDeltaTime, triggersOut); evaluateAndBlendChildren(animVars, context, triggersOut, alpha, prevPoseIndex, nextPoseIndex, prevDeltaTime, nextDeltaTime); - _animStack[_children[0]->getID()] = parentAlpha; + context.setDebugAlpha(_children[0]->getID(), parentDebugAlpha, _children[0]->getType()); } else { auto clampedAlpha = glm::clamp(_alpha, 0.0f, (float)(_children.size() - 1)); auto prevPoseIndex = glm::floor(clampedAlpha); @@ -87,17 +85,11 @@ const AnimPoseVec& AnimBlendLinearMove::evaluate(const AnimVariantMap& animVars, setFrameAndPhase(dt, alpha, prevPoseIndex, nextPoseIndex, &prevDeltaTime, &nextDeltaTime, triggersOut); evaluateAndBlendChildren(animVars, context, triggersOut, alpha, prevPoseIndex, nextPoseIndex, prevDeltaTime, nextDeltaTime); - // weights are for animation stack debug purposes only. - float weight1 = 0.0f; - float weight2 = 0.0f; if (prevPoseIndex == nextPoseIndex) { - weight2 = 1.0f; - _animStack[_children[nextPoseIndex]->getID()] = weight2 * parentAlpha; + context.setDebugAlpha(_children[nextPoseIndex]->getID(), parentDebugAlpha, _children[nextPoseIndex]->getType()); } else { - weight2 = alpha; - weight1 = 1.0f - weight2; - _animStack[_children[prevPoseIndex]->getID()] = weight1 * parentAlpha; - _animStack[_children[nextPoseIndex]->getID()] = weight2 * parentAlpha; + context.setDebugAlpha(_children[prevPoseIndex]->getID(), (1.0f - alpha) * parentDebugAlpha, _children[prevPoseIndex]->getType()); + context.setDebugAlpha(_children[nextPoseIndex]->getID(), alpha * parentDebugAlpha, _children[nextPoseIndex]->getType()); } } diff --git a/libraries/animation/src/AnimContext.h b/libraries/animation/src/AnimContext.h index e8bf5c34eb..ecfb94a28e 100644 --- a/libraries/animation/src/AnimContext.h +++ b/libraries/animation/src/AnimContext.h @@ -14,8 +14,27 @@ #include #include +#include +#include +#include + +enum class AnimNodeType { + Clip = 0, + BlendLinear, + BlendLinearMove, + Overlay, + StateMachine, + Manipulator, + InverseKinematics, + DefaultPose, + TwoBoneIK, + PoleVectorConstraint, + NumTypes +}; + class AnimContext { public: + AnimContext() {} AnimContext(bool enableDebugDrawIKTargets, bool enableDebugDrawIKConstraints, bool enableDebugDrawIKChains, const glm::mat4& geometryToRigMatrix, const glm::mat4& rigToWorldMatrix); @@ -25,6 +44,26 @@ public: const glm::mat4& getGeometryToRigMatrix() const { return _geometryToRigMatrix; } const glm::mat4& getRigToWorldMatrix() const { return _rigToWorldMatrix; } + float getDebugAlpha(const QString& key) const { + auto it = _debugAlphaMap.find(key); + if (it != _debugAlphaMap.end()) { + return std::get<0>(it->second); + } else { + return 1.0f; + } + } + + using DebugAlphaMapValue = std::tuple; + using DebugAlphaMap = std::map; + + void setDebugAlpha(const QString& key, float alpha, AnimNodeType type) const { + _debugAlphaMap[key] = DebugAlphaMapValue(alpha, type); + } + + const DebugAlphaMap& getDebugAlphaMap() const { + return _debugAlphaMap; + } + protected: bool _enableDebugDrawIKTargets { false }; @@ -32,6 +71,9 @@ protected: bool _enableDebugDrawIKChains { false }; glm::mat4 _geometryToRigMatrix; glm::mat4 _rigToWorldMatrix; + + // used for debugging internal state of animation system. + mutable DebugAlphaMap _debugAlphaMap; }; #endif // hifi_AnimContext_h diff --git a/libraries/animation/src/AnimNode.cpp b/libraries/animation/src/AnimNode.cpp index a8e76617ae..f055e6b473 100644 --- a/libraries/animation/src/AnimNode.cpp +++ b/libraries/animation/src/AnimNode.cpp @@ -12,10 +12,6 @@ #include -std::map AnimNode::_animStack = { - {"none", 0.0f} -}; - AnimNode::Pointer AnimNode::getParent() { return _parent.lock(); } diff --git a/libraries/animation/src/AnimNode.h b/libraries/animation/src/AnimNode.h index 1f14889ce4..1a12bb8ddb 100644 --- a/libraries/animation/src/AnimNode.h +++ b/libraries/animation/src/AnimNode.h @@ -36,19 +36,7 @@ class QJsonObject; class AnimNode : public std::enable_shared_from_this { public: - enum class Type { - Clip = 0, - BlendLinear, - BlendLinearMove, - Overlay, - StateMachine, - Manipulator, - InverseKinematics, - DefaultPose, - TwoBoneIK, - PoleVectorConstraint, - NumTypes - }; + using Type = AnimNodeType; using Pointer = std::shared_ptr; using ConstPointer = std::shared_ptr; @@ -84,7 +72,6 @@ public: } void setCurrentFrame(float frame); - const std::map getAnimStack() { return _animStack; } template bool traverse(F func) { @@ -127,9 +114,6 @@ protected: std::weak_ptr _parent; std::vector _outputJointNames; - // global available to Stats.h - static std::map _animStack; - // no copies AnimNode(const AnimNode&) = delete; AnimNode& operator=(const AnimNode&) = delete; diff --git a/libraries/animation/src/AnimStateMachine.cpp b/libraries/animation/src/AnimStateMachine.cpp index 90fd425ae5..00ae5e6d39 100644 --- a/libraries/animation/src/AnimStateMachine.cpp +++ b/libraries/animation/src/AnimStateMachine.cpp @@ -23,9 +23,7 @@ AnimStateMachine::~AnimStateMachine() { const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) { - if (_id.contains("userAnimStateMachine")) { - _animStack.clear(); - } + float parentDebugAlpha = context.getDebugAlpha(_id); QString desiredStateID = animVars.lookup(_currentStateVar, _currentState->getID()); if (_currentState->getID() != desiredStateID) { @@ -33,8 +31,6 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, co bool foundState = false; for (auto& state : _states) { if (state->getID() == desiredStateID) { - // parenthesis means previous state, which is a snapshot. - _previousStateID = "(" + _currentState->getID() + ")"; switchState(animVars, context, state); foundState = true; break; @@ -48,8 +44,6 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, co // evaluate currentState transitions auto desiredState = evaluateTransitions(animVars); if (desiredState != _currentState) { - // parenthesis means previous state, which is a snapshot. - _previousStateID = "(" + _currentState->getID() + ")"; switchState(animVars, context, desiredState); } @@ -57,17 +51,8 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, co auto currentStateNode = _children[_currentState->getChildIndex()]; assert(currentStateNode); - if (!_previousStateID.contains("none")) { - _animStack[_previousStateID] = 1.0f - _alpha; - } - if (_duringInterp) { _alpha += _alphaVel * dt; - if (_alpha > 1.0f) { - _animStack[_currentState->getID()] = 1.0f; - } else { - _animStack[_currentState->getID()] = _alpha; - } if (_alpha < 1.0f) { AnimPoseVec* nextPoses = nullptr; AnimPoseVec* prevPoses = nullptr; @@ -88,18 +73,16 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, co if (_poses.size() > 0 && nextPoses && prevPoses && nextPoses->size() > 0 && prevPoses->size() > 0) { ::blend(_poses.size(), &(prevPoses->at(0)), &(nextPoses->at(0)), _alpha, &_poses[0]); } + context.setDebugAlpha(_currentState->getID(), _alpha * parentDebugAlpha, _children[_currentState->getChildIndex()]->getType()); } else { _duringInterp = false; - if (_animStack.count(_previousStateID) > 0) { - _animStack.erase(_previousStateID); - } - _previousStateID = "none"; _prevPoses.clear(); _nextPoses.clear(); } } + if (!_duringInterp) { - _animStack[_currentState->getID()] = 1.0f; + context.setDebugAlpha(_currentState->getID(), parentDebugAlpha, _children[_currentState->getChildIndex()]->getType()); _poses = currentStateNode->evaluate(animVars, context, dt, triggersOut); } processOutputJoints(triggersOut); diff --git a/libraries/animation/src/AnimStateMachine.h b/libraries/animation/src/AnimStateMachine.h index b20e5203a1..8e1e1b7bd8 100644 --- a/libraries/animation/src/AnimStateMachine.h +++ b/libraries/animation/src/AnimStateMachine.h @@ -138,7 +138,6 @@ protected: float _alpha = 0.0f; AnimPoseVec _prevPoses; AnimPoseVec _nextPoses; - QString _previousStateID { "none" }; State::Pointer _currentState; std::vector _states; diff --git a/libraries/animation/src/AnimVariant.cpp b/libraries/animation/src/AnimVariant.cpp index 483a7999c9..509462984a 100644 --- a/libraries/animation/src/AnimVariant.cpp +++ b/libraries/animation/src/AnimVariant.cpp @@ -67,6 +67,7 @@ QScriptValue AnimVariantMap::animVariantMapToScriptValue(QScriptEngine* engine, } return target; } + void AnimVariantMap::copyVariantsFrom(const AnimVariantMap& other) { for (auto& pair : other._map) { _map[pair.first] = pair.second; @@ -124,3 +125,43 @@ void AnimVariantMap::animVariantMapFromScriptValue(const QScriptValue& source) { } } } + +std::map AnimVariantMap::toDebugMap() const { + std::map result; + for (auto& pair : _map) { + switch (pair.second.getType()) { + case AnimVariant::Type::Bool: + result[pair.first] = QString("%1").arg(pair.second.getBool()); + break; + case AnimVariant::Type::Int: + result[pair.first] = QString("%1").arg(pair.second.getInt()); + break; + case AnimVariant::Type::Float: + result[pair.first] = QString::number(pair.second.getFloat(), 'f', 3); + break; + case AnimVariant::Type::Vec3: { + glm::vec3 value = pair.second.getVec3(); + result[pair.first] = QString("(%1, %2, %3)"). + arg(QString::number(value.x, 'f', 3)). + arg(QString::number(value.y, 'f', 3)). + arg(QString::number(value.z, 'f', 3)); + break; + } + case AnimVariant::Type::Quat: { + glm::quat value = pair.second.getQuat(); + result[pair.first] = QString("(%1, %2, %3, %4)"). + arg(QString::number(value.x, 'f', 3)). + arg(QString::number(value.y, 'f', 3)). + arg(QString::number(value.z, 'f', 3)). + arg(QString::number(value.w, 'f', 3)); + break; + } + case AnimVariant::Type::String: + result[pair.first] = pair.second.getString(); + break; + default: + assert(("invalid AnimVariant::Type", false)); + } + } + return result; +} diff --git a/libraries/animation/src/AnimVariant.h b/libraries/animation/src/AnimVariant.h index d383b5abb8..0f921984b1 100644 --- a/libraries/animation/src/AnimVariant.h +++ b/libraries/animation/src/AnimVariant.h @@ -235,6 +235,9 @@ public: void animVariantMapFromScriptValue(const QScriptValue& object); void copyVariantsFrom(const AnimVariantMap& other); + // For stat debugging. + std::map toDebugMap() const; + #ifdef NDEBUG void dump() const { qCDebug(animation) << "AnimVariantMap ="; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 13cf165dac..91d4e0f9d3 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1061,8 +1061,10 @@ void Rig::updateAnimations(float deltaTime, const glm::mat4& rootTransform, cons // animations haven't fully loaded yet. _internalPoseSet._relativePoses = _animSkeleton->getRelativeDefaultPoses(); } + _lastAnimVars = _animVars; _animVars.clearTriggers(); _animVars = triggersOut; + _lastContext = context; } applyOverridePoses(); buildAbsoluteRigPoses(_internalPoseSet._relativePoses, _internalPoseSet._absolutePoses); diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index accbcccbbc..95a4b6f40d 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -222,7 +222,9 @@ public: // input assumed to be in rig space void computeHeadFromHMD(const AnimPose& hmdPose, glm::vec3& headPositionOut, glm::quat& headOrientationOut) const; - const std::map getAnimStack() { return _animNode->getAnimStack(); } + // used to debug animation playback + const AnimContext::DebugAlphaMap& getDebugAlphaMap() const { return _lastContext.getDebugAlphaMap(); } + const AnimVariantMap& getAnimVars() const { return _lastAnimVars; } void toggleSmoothPoleVectors() { _smoothPoleVectors = !_smoothPoleVectors; }; signals: @@ -388,6 +390,9 @@ protected: int _rigId; bool _headEnabled { false }; + + AnimContext _lastContext; + AnimVariantMap _lastAnimVars; }; #endif /* defined(__hifi__Rig__) */ From 8420afd14344625b41b636b374f5d0e8c3fe249f Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 6 Sep 2018 14:00:33 +1200 Subject: [PATCH 282/545] Fix title not not going back to "Settings" upon Save or Cancel --- interface/resources/qml/hifi/tablet/TabletMenuStack.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/hifi/tablet/TabletMenuStack.qml b/interface/resources/qml/hifi/tablet/TabletMenuStack.qml index 4d36a57793..fe636dafa5 100644 --- a/interface/resources/qml/hifi/tablet/TabletMenuStack.qml +++ b/interface/resources/qml/hifi/tablet/TabletMenuStack.qml @@ -1,5 +1,5 @@ // -// MessageDialog.qml +// TabletMenuStack.qml // // Created by Dante Ruiz on 13 Feb 2017 // Copyright 2016 High Fidelity, Inc. @@ -66,7 +66,7 @@ Item { function popSource() { console.log("trying to pop page"); - d.pop(); + closeLastMenu(); } function toModel(items, newMenu) { From ab47e16be1f8bd14c2308b60868b411641d50759 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 6 Sep 2018 14:35:08 +1200 Subject: [PATCH 283/545] Fix up titles and leading white space of some dev menu tablet dialogs --- .../resources/qml/hifi/dialogs/TabletDCDialog.qml | 3 ++- .../qml/hifi/dialogs/TabletEntityStatistics.qml | 11 +++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/interface/resources/qml/hifi/dialogs/TabletDCDialog.qml b/interface/resources/qml/hifi/dialogs/TabletDCDialog.qml index 1ec7ea3e0e..afe06897df 100644 --- a/interface/resources/qml/hifi/dialogs/TabletDCDialog.qml +++ b/interface/resources/qml/hifi/dialogs/TabletDCDialog.qml @@ -18,6 +18,7 @@ import "../../windows" Rectangle { id: root objectName: "DCConectionTiming" + property string title: "Domain Connection Timing" signal sendToScript(var message); property bool isHMD: false @@ -33,7 +34,7 @@ Rectangle { Row { id: header anchors.top: parent.top - anchors.topMargin: hifi.dimensions.tabletMenuHeader + anchors.topMargin: hifi.dimensions.contentMargin.y anchors.leftMargin: 5 anchors.rightMargin: 5 anchors.left: parent.left diff --git a/interface/resources/qml/hifi/dialogs/TabletEntityStatistics.qml b/interface/resources/qml/hifi/dialogs/TabletEntityStatistics.qml index 7bce460283..24798af21a 100644 --- a/interface/resources/qml/hifi/dialogs/TabletEntityStatistics.qml +++ b/interface/resources/qml/hifi/dialogs/TabletEntityStatistics.qml @@ -18,6 +18,7 @@ import "../../windows" Rectangle { id: root objectName: "EntityStatistics" + property string title: "Entity Statistics" signal sendToScript(var message); property bool isHMD: false @@ -40,6 +41,7 @@ Rectangle { id: scrollView width: parent.width anchors.top: parent.top + anchors.topMargin: hifi.dimensions.contentMargin.y anchors.bottom: parent.bottom anchors.bottomMargin: hifi.dimensions.tabletMenuHeader contentWidth: column.implicitWidth @@ -48,10 +50,15 @@ Rectangle { Column { id: column - anchors.margins: 10 + anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right - y: hifi.dimensions.tabletMenuHeader //-bgNavBar + anchors { + topMargin: 0 + leftMargin: 10 + rightMargin: 10 + bottomMargin: 0 + } spacing: 20 TabletEntityStatisticsItem { From 78fa52285f25ebbd68f3318b724fe4bd8c8f726f Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Wed, 5 Sep 2018 23:48:21 -0700 Subject: [PATCH 284/545] adding show password toggle in textfield --- interface/resources/images/eyeClosed.svg | 5 +++ interface/resources/images/eyeOpen.svg | 4 +++ .../qml/LoginDialog/LinkAccountBody.qml | 36 +++++++++++++++---- 3 files changed, 38 insertions(+), 7 deletions(-) create mode 100644 interface/resources/images/eyeClosed.svg create mode 100644 interface/resources/images/eyeOpen.svg diff --git a/interface/resources/images/eyeClosed.svg b/interface/resources/images/eyeClosed.svg new file mode 100644 index 0000000000..6719471b3d --- /dev/null +++ b/interface/resources/images/eyeClosed.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/interface/resources/images/eyeOpen.svg b/interface/resources/images/eyeOpen.svg new file mode 100644 index 0000000000..ec5ceb5238 --- /dev/null +++ b/interface/resources/images/eyeOpen.svg @@ -0,0 +1,4 @@ + + + + diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index 423f6cc73b..c40dff61ee 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -86,7 +86,7 @@ Item { width: 48 height: 48 } - + ShortcutText { id: mainTextContainer anchors { @@ -142,6 +142,7 @@ Item { onLinkActivated: loginDialog.openUrl(link) } + onFocusChanged: { root.text = ""; } @@ -151,7 +152,6 @@ Item { id: passwordField width: parent.width placeholderText: "Password" - echoMode: showPassword.checked ? TextInput.Normal : TextInput.Password activeFocusOnPress: true ShortcutText { @@ -177,12 +177,34 @@ Item { root.isPassword = true; } - Keys.onReturnPressed: linkAccountBody.login() - } + Image { + id: showPasswordImage + x: parent.width - 40 + height: parent.height + width: parent.width - (parent.width - 40) + source: "../../images/eyeOpen.svg" + } - CheckBox { - id: showPassword - text: "Show password" + Rectangle { + z: 10 + x: parent.width - 40 + width: parent.width - (parent.width - 40) + height: parent.height + color: "transparent" + MouseArea { + id: passwordFieldMouseArea + anchors.fill: parent + acceptedButtons: Qt.LeftButton + property bool showPassword: false + onClicked: { + showPassword = !showPassword; + passwordField.echoMode = showPassword ? TextInput.Normal : TextInput.Password; + showPasswordImage.source = showPassword ? "../../images/eyeClosed.svg" : "../../images/eyeOpen.svg"; + } + } + } + + Keys.onReturnPressed: linkAccountBody.login() } InfoItem { From 6d055ba1360e492183d5aa692af7182a415a018c Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Wed, 5 Sep 2018 23:49:49 -0700 Subject: [PATCH 285/545] changing sign up label --- interface/resources/qml/LoginDialog/LinkAccountBody.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index c40dff61ee..aed34609e4 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -254,7 +254,7 @@ Item { RalewaySemiBold { size: hifi.fontSizes.inputLabel anchors.verticalCenter: parent.verticalCenter - text: qsTr("Don't have an account?") + text: qsTr("New to High Fidelity?") } Button { From 3f1eba418dd210c6435af80df009b460dcb5f185 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Thu, 6 Sep 2018 00:07:23 -0700 Subject: [PATCH 286/545] modifying location of links for user/pw --- .../qml/LoginDialog/LinkAccountBody.qml | 68 +++++++++---------- 1 file changed, 31 insertions(+), 37 deletions(-) diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index aed34609e4..caf5ce0e53 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -116,7 +116,6 @@ Item { } spacing: 2 * hifi.dimensions.contentSpacing.y - TextField { id: usernameField text: Settings.getValue("wallet/savedUsername", ""); @@ -125,28 +124,25 @@ Item { placeholderText: "Username or Email" activeFocusOnPress: true - ShortcutText { - z: 10 - anchors { - left: usernameField.right - top: usernameField.bottom - leftMargin: usernameField.textFieldLabel.contentWidth + 10 - topMargin: -19 - } - - text: "Forgot Username?" - - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - linkColor: hifi.colors.blueAccent - - onLinkActivated: loginDialog.openUrl(link) - } - onFocusChanged: { root.text = ""; } } + ShortcutText { + z: 10 + anchors { + leftMargin: usernameField.textFieldLabel.contentWidth + 10 + topMargin: -19 + } + + text: "Forgot Username?" + + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignRight + linkColor: hifi.colors.blueAccent + + onLinkActivated: loginDialog.openUrl(link) + } TextField { id: passwordField @@ -154,24 +150,6 @@ Item { placeholderText: "Password" activeFocusOnPress: true - ShortcutText { - z: 10 - anchors { - left: passwordField.right - top: passwordField.bottom - leftMargin: passwordField.textFieldLabel.contentWidth + 10 - topMargin: -19 - } - - text: "Forgot Password?" - - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - linkColor: hifi.colors.blueAccent - - onLinkActivated: loginDialog.openUrl(link) - } - onFocusChanged: { root.text = ""; root.isPassword = true; @@ -207,6 +185,22 @@ Item { Keys.onReturnPressed: linkAccountBody.login() } + ShortcutText { + z: 10 + anchors { + leftMargin: passwordField.textFieldLabel.contentWidth + 10 + topMargin: -19 + } + + text: "Forgot Password?" + + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + linkColor: hifi.colors.blueAccent + + onLinkActivated: loginDialog.openUrl(link) + } + InfoItem { id: additionalInformation From 105a615745361c85c2d4b2f6a4e6e6d4e99445db Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 22 Aug 2018 14:09:20 -0700 Subject: [PATCH 287/545] Fix no-ui crashes --- interface/src/Application.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2fe67ec5cb..21b953b686 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2663,6 +2663,10 @@ Application::~Application() { void Application::initializeGL() { qCDebug(interfaceapp) << "Created Display Window."; +#ifdef DISABLE_QML + setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity); +#endif + // initialize glut for shape drawing; Qt apparently initializes it on OS X if (_isGLInitialized) { return; @@ -6870,6 +6874,9 @@ bool Application::askToLoadScript(const QString& scriptFilenameOrURL) { shortName = shortName.mid(startIndex, endIndex - startIndex); } +#ifdef DISABLE_QML + DependencyManager::get()->loadScript(scriptFilenameOrURL); +#else QString message = "Would you like to run this script:\n" + shortName; ModalDialogListener* dlg = OffscreenUi::asyncQuestion(getWindow(), "Run Script", message, QMessageBox::Yes | QMessageBox::No); @@ -6884,7 +6891,7 @@ bool Application::askToLoadScript(const QString& scriptFilenameOrURL) { } QObject::disconnect(dlg, &ModalDialogListener::response, this, nullptr); }); - +#endif return true; } From b6247e08503260903ba4b8307d28db73f2517f10 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 23 Aug 2018 12:19:07 -0700 Subject: [PATCH 288/545] Remove cmake spam --- cmake/macros/AutoScribeShader.cmake | 1 - cmake/macros/TargetJson.cmake | 1 - 2 files changed, 2 deletions(-) diff --git a/cmake/macros/AutoScribeShader.cmake b/cmake/macros/AutoScribeShader.cmake index 1d1e5970d9..9c5ad70c78 100755 --- a/cmake/macros/AutoScribeShader.cmake +++ b/cmake/macros/AutoScribeShader.cmake @@ -9,7 +9,6 @@ # macro(AUTOSCRIBE_SHADER) - message(STATUS "Processing shader ${SHADER_FILE}") unset(SHADER_INCLUDE_FILES) # Grab include files foreach(includeFile ${ARGN}) diff --git a/cmake/macros/TargetJson.cmake b/cmake/macros/TargetJson.cmake index 057024cd0a..9262c2ce48 100644 --- a/cmake/macros/TargetJson.cmake +++ b/cmake/macros/TargetJson.cmake @@ -8,6 +8,5 @@ macro(TARGET_JSON) add_dependency_external_projects(json) find_package(JSON REQUIRED) - message("JSON_INCLUDE_DIRS ${JSON_INCLUDE_DIRS}") target_include_directories(${TARGET_NAME} PUBLIC ${JSON_INCLUDE_DIRS}) endmacro() \ No newline at end of file From 35d86dd7982291f096686a0912da30e3b3bfd444 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 23 Aug 2018 12:19:50 -0700 Subject: [PATCH 289/545] Fail unit test on non-compiling pipelines --- tests/shaders/src/ShaderTests.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/shaders/src/ShaderTests.cpp b/tests/shaders/src/ShaderTests.cpp index 4dd15710f9..03dc034cd0 100644 --- a/tests/shaders/src/ShaderTests.cpp +++ b/tests/shaders/src/ShaderTests.cpp @@ -230,8 +230,8 @@ void ShaderTests::testShaderLoad() { auto glBackend = std::static_pointer_cast(_gpuContext->getBackend()); auto glshader = gpu::gl::GLShader::sync(*glBackend, *program); if (!glshader) { - qDebug() << "Failed to compile or link vertex " << vertexId << " fragment " << fragmentId; - continue; + qWarning() << "Failed to compile or link vertex " << vertexId << " fragment " << fragmentId; + QFAIL("Program link error"); } QVERIFY(glshader != nullptr); @@ -301,7 +301,7 @@ void ShaderTests::testShaderLoad() { QFAIL(error.what()); } - for (uint32_t i = 0; i <= maxShader; ++i) { + for (uint32_t i = 1; i <= maxShader; ++i) { auto used = usedShaders.count(i); if (0 != usedShaders.count(i)) { continue; From ac84a498b391de3c5e683a6d95851bb66b2bcb8c Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 23 Aug 2018 12:22:39 -0700 Subject: [PATCH 290/545] Cleanup dead declarations --- libraries/procedural/src/procedural/ShaderConstants.h | 1 - libraries/render-utils/src/DeferredLightingEffect.cpp | 1 - libraries/render-utils/src/GeometryCache.cpp | 2 -- libraries/render-utils/src/HighlightEffect.cpp | 1 - libraries/render-utils/src/render-utils/ShaderConstants.h | 5 ----- libraries/render-utils/src/render-utils/fxaa.slp | 1 + 6 files changed, 1 insertion(+), 10 deletions(-) create mode 100644 libraries/render-utils/src/render-utils/fxaa.slp diff --git a/libraries/procedural/src/procedural/ShaderConstants.h b/libraries/procedural/src/procedural/ShaderConstants.h index 1995996c97..bfbf2a2691 100644 --- a/libraries/procedural/src/procedural/ShaderConstants.h +++ b/libraries/procedural/src/procedural/ShaderConstants.h @@ -14,7 +14,6 @@ #ifndef PROCEDURAL_SHADER_CONSTANTS_H #define PROCEDURAL_SHADER_CONSTANTS_H -// Polyvox #define PROCEDURAL_UNIFORM_TIME 200 #define PROCEDURAL_UNIFORM_DATE 201 #define PROCEDURAL_UNIFORM_FRAME_COUNT 202 diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index af5a3f3e63..3b23711a64 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -32,7 +32,6 @@ namespace ru { using render_utils::slot::texture::Texture; using render_utils::slot::buffer::Buffer; - using render_utils::slot::uniform::Uniform; } namespace gr { diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index cbc9b40129..2fe811c97b 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -2104,9 +2104,7 @@ void GeometryCache::useSimpleDrawPipeline(gpu::Batch& batch, bool noBlend) { auto stateNoBlend = std::make_shared(); PrepareStencil::testMaskDrawShape(*stateNoBlend); - auto noBlendPS = gpu::Shader::createVertex(shader::gpu::fragment::DrawTextureOpaque); auto programNoBlend = gpu::Shader::createProgram(shader::render_utils::program::standardDrawTextureNoBlend); - _standardDrawPipelineNoBlend = gpu::Pipeline::create(programNoBlend, stateNoBlend); }); diff --git a/libraries/render-utils/src/HighlightEffect.cpp b/libraries/render-utils/src/HighlightEffect.cpp index 7e2e55c768..11326b1120 100644 --- a/libraries/render-utils/src/HighlightEffect.cpp +++ b/libraries/render-utils/src/HighlightEffect.cpp @@ -28,7 +28,6 @@ using namespace render; namespace ru { using render_utils::slot::texture::Texture; using render_utils::slot::buffer::Buffer; - using render_utils::slot::uniform::Uniform; } namespace gr { diff --git a/libraries/render-utils/src/render-utils/ShaderConstants.h b/libraries/render-utils/src/render-utils/ShaderConstants.h index 6a88a62287..ccf6314a39 100644 --- a/libraries/render-utils/src/render-utils/ShaderConstants.h +++ b/libraries/render-utils/src/render-utils/ShaderConstants.h @@ -43,9 +43,6 @@ #define RENDER_UTILS_BUFFER_AMBIENT_LIGHT 6 #define RENDER_UTILS_BUFFER_LIGHT_INDEX 7 -#define RENDER_UTILS_UNIFORM_LIGHT_RADIUS 0 -#define RENDER_UTILS_UNIFORM_LIGHT_TEXCOORD_TRANSFORM 1 - // Deferred lighting resolution #define RENDER_UTILS_TEXTURE_DEFERRRED_COLOR 0 #define RENDER_UTILS_TEXTURE_DEFERRRED_NORMAL 1 @@ -140,8 +137,6 @@ enum Uniform { TextOutline = RENDER_UTILS_UNIFORM_TEXT_OUTLINE, TaaSharpenIntensity = GPU_UNIFORM_EXTRA0, HighlightOutlineWidth = GPU_UNIFORM_EXTRA0, - LightRadius = RENDER_UTILS_UNIFORM_LIGHT_RADIUS, - TexcoordTransform = RENDER_UTILS_UNIFORM_LIGHT_TEXCOORD_TRANSFORM, }; } diff --git a/libraries/render-utils/src/render-utils/fxaa.slp b/libraries/render-utils/src/render-utils/fxaa.slp new file mode 100644 index 0000000000..c2c4bfbebd --- /dev/null +++ b/libraries/render-utils/src/render-utils/fxaa.slp @@ -0,0 +1 @@ +VERTEX gpu::vertex::DrawUnitQuadTexcoord From c8eb4da6b61e7f1e9da6008ef7068202049b47d5 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 23 Aug 2018 15:36:32 -0700 Subject: [PATCH 291/545] Remove simple draw task uniforms --- libraries/gpu/src/gpu/DrawColor.slf | 10 +++++++--- libraries/gpu/src/gpu/DrawColoredTexture.slf | 13 +++++++++---- libraries/render/src/render/DrawTask.cpp | 17 +++++++++++------ libraries/render/src/render/DrawTask.h | 3 ++- libraries/render/src/render/drawItemBounds.slv | 15 +++++++++++---- 5 files changed, 40 insertions(+), 18 deletions(-) diff --git a/libraries/gpu/src/gpu/DrawColor.slf b/libraries/gpu/src/gpu/DrawColor.slf index 2540d56d69..fdea26fa68 100644 --- a/libraries/gpu/src/gpu/DrawColor.slf +++ b/libraries/gpu/src/gpu/DrawColor.slf @@ -13,12 +13,16 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -<@include gpu/ShaderConstants.h@> +struct DrawColorParams { + vec4 color; +}; -layout(location=GPU_UNIFORM_COLOR) uniform vec4 color; +layout(binding=0) uniform drawColorParamsBuffer { + DrawColorParams params; +}; layout(location=0) out vec4 outFragColor; void main(void) { - outFragColor = color; + outFragColor = params.color; } diff --git a/libraries/gpu/src/gpu/DrawColoredTexture.slf b/libraries/gpu/src/gpu/DrawColoredTexture.slf index 632bf18391..0fe3707b1c 100755 --- a/libraries/gpu/src/gpu/DrawColoredTexture.slf +++ b/libraries/gpu/src/gpu/DrawColoredTexture.slf @@ -13,14 +13,19 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -<@include gpu/ShaderConstants.h@> - layout(binding=0) uniform sampler2D colorMap; -layout(location=GPU_UNIFORM_COLOR) uniform vec4 color; + +struct DrawColorParams { + vec4 color; +}; + +layout(binding=0) uniform drawColorParams { + DrawColorParams params; +}; layout(location=0) in vec2 varTexCoord0; layout(location=0) out vec4 outFragColor; void main(void) { - outFragColor = texture(colorMap, varTexCoord0) * color; + outFragColor = texture(colorMap, varTexCoord0) * params.color; } diff --git a/libraries/render/src/render/DrawTask.cpp b/libraries/render/src/render/DrawTask.cpp index 8fb800291e..12f75049b2 100755 --- a/libraries/render/src/render/DrawTask.cpp +++ b/libraries/render/src/render/DrawTask.cpp @@ -184,8 +184,13 @@ void DrawBounds::run(const RenderContextPointer& renderContext, _drawBuffer = std::make_shared(sizeOfItemBound); } - _drawBuffer->setData(numItems * sizeOfItemBound, (const gpu::Byte*) items.data()); + if (!_paramsBuffer) { + _paramsBuffer = std::make_shared(sizeof(vec4), nullptr); + } + _drawBuffer->setData(numItems * sizeOfItemBound, (const gpu::Byte*) items.data()); + glm::vec4 color(glm::vec3(0.0f), -(float) numItems); + _paramsBuffer->setSubData(0, color); gpu::doInBatch("DrawBounds::run", args->_context, [&](gpu::Batch& batch) { args->_batch = &batch; @@ -202,7 +207,7 @@ void DrawBounds::run(const RenderContextPointer& renderContext, batch.setPipeline(getPipeline()); glm::vec4 color(glm::vec3(0.0f), -(float) numItems); - batch._glUniform4fv(gpu::slot::uniform::Color, 1, (const float*)(&color)); + batch.setUniformBuffer(0, _paramsBuffer); batch.setResourceBuffer(0, _drawBuffer); static const int NUM_VERTICES_PER_CUBE = 24; @@ -212,9 +217,10 @@ void DrawBounds::run(const RenderContextPointer& renderContext, gpu::Stream::FormatPointer DrawQuadVolume::_format; -DrawQuadVolume::DrawQuadVolume(const glm::vec3& color) : - _color{ color } { +DrawQuadVolume::DrawQuadVolume(const glm::vec3& color) { _meshVertices = gpu::BufferView(std::make_shared(sizeof(glm::vec3) * 8, nullptr), gpu::Element::VEC3F_XYZ); + _params = std::make_shared(sizeof(glm::vec4), nullptr); + _params->setSubData(0, vec4(color, 1.0)); if (!_format) { _format = std::make_shared(); _format->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0); @@ -248,8 +254,7 @@ void DrawQuadVolume::run(const render::RenderContextPointer& renderContext, cons batch.setProjectionTransform(projMat); batch.setViewTransform(viewMat); batch.setPipeline(getPipeline()); - - batch._glUniform4f(0, _color.x, _color.y, _color.z, 1.0f); + batch.setUniformBuffer(0, _params); batch.setInputFormat(_format); batch.setInputBuffer(gpu::Stream::POSITION, _meshVertices); batch.setIndexBuffer(indices); diff --git a/libraries/render/src/render/DrawTask.h b/libraries/render/src/render/DrawTask.h index 6b98fb2977..1ef4b8caf1 100755 --- a/libraries/render/src/render/DrawTask.h +++ b/libraries/render/src/render/DrawTask.h @@ -66,6 +66,7 @@ private: const gpu::PipelinePointer getPipeline(); gpu::PipelinePointer _boundsPipeline; gpu::BufferPointer _drawBuffer; + gpu::BufferPointer _paramsBuffer; }; class DrawQuadVolumeConfig : public render::JobConfig { @@ -95,7 +96,7 @@ protected: const gpu::BufferView& indices, int indexCount); gpu::BufferView _meshVertices; - glm::vec3 _color; + gpu::BufferPointer _params; bool _isUpdateEnabled{ true }; static gpu::Stream::FormatPointer _format; diff --git a/libraries/render/src/render/drawItemBounds.slv b/libraries/render/src/render/drawItemBounds.slv index 8925009160..ea4d0f24e6 100644 --- a/libraries/render/src/render/drawItemBounds.slv +++ b/libraries/render/src/render/drawItemBounds.slv @@ -20,7 +20,14 @@ <@include gpu/Color.slh@> <$declareColorWheel()$> -layout(location=GPU_UNIFORM_COLOR) uniform vec4 inColor; +struct DrawItemBoundsParams { + vec4 color; +}; + +layout(binding=0) uniform drawItemBoundsParamsBuffer { + DrawItemBoundsParams params; +}; + struct ItemBound { vec4 id_boundPos; @@ -91,10 +98,10 @@ void main(void) { TransformObject obj = getTransformObject(); <$transformModelToClipPos(cam, obj, pos, gl_Position)$> - if (inColor.w < 0.0) { - varColor = vec4(colorWheel(float(boundID)/(-inColor.w)), 1.0); + if (params.color.w < 0.0) { + varColor = vec4(colorWheel(float(boundID)/(-params.color.w)), 1.0); } else { - varColor = vec4(colorWheel(float(inColor.w)), 1.0); + varColor = vec4(colorWheel(float(params.color.w)), 1.0); } varTexcoord = vec2(cubeVec.w, length(boundDim)); From 719ae25adb583affd795fd7c9f80a5b26ada64b2 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 23 Aug 2018 16:00:06 -0700 Subject: [PATCH 292/545] Remove uniforms from drawCellBounds --- .../render/src/render/DrawSceneOctree.cpp | 19 +++++++++++++++---- libraries/render/src/render/DrawSceneOctree.h | 2 ++ .../render/src/render/drawCellBounds.slv | 3 +-- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/libraries/render/src/render/DrawSceneOctree.cpp b/libraries/render/src/render/DrawSceneOctree.cpp index 2cb8a5d8ef..60cfc64e27 100644 --- a/libraries/render/src/render/DrawSceneOctree.cpp +++ b/libraries/render/src/render/DrawSceneOctree.cpp @@ -36,6 +36,9 @@ const gpu::PipelinePointer DrawSceneOctree::getDrawCellBoundsPipeline() { // Good to go add the brand new pipeline _drawCellBoundsPipeline = gpu::Pipeline::create(program, state); + _cellBoundsFormat = std::make_shared(); + _cellBoundsFormat->setAttribute(0, 0, gpu::Element(gpu::VEC4, gpu::INT32, gpu::XYZW), 0, gpu::Stream::PER_INSTANCE); + _cellBoundsBuffer = std::make_shared(); } return _drawCellBoundsPipeline; } @@ -82,8 +85,11 @@ void DrawSceneOctree::run(const RenderContextPointer& renderContext, const ItemS // bind the one gpu::Pipeline we need batch.setPipeline(getDrawCellBoundsPipeline()); + batch.setInputFormat(_cellBoundsFormat); - auto drawCellBounds = [this, &scene, &batch](const std::vector& cells) { + std::vector cellBounds; + auto drawCellBounds = [this, &cellBounds, &scene, &batch](const std::vector& cells) { + cellBounds.reserve(cellBounds.size() + cells.size()); for (const auto& cellID : cells) { auto cell = scene->getSpatialTree().getConcreteCell(cellID); auto cellLoc = cell.getlocation(); @@ -98,14 +104,19 @@ void DrawSceneOctree::run(const RenderContextPointer& renderContext, const ItemS } else if (!empty && !_showVisibleCells) { continue; } - - batch._glUniform4iv(gpu::slot::uniform::Extra0, 1, ((const int*)(&cellLocation))); - batch.draw(gpu::LINES, 24, 0); + cellBounds.push_back(cellLocation); } }; drawCellBounds(inSelection.cellSelection.insideCells); drawCellBounds(inSelection.cellSelection.partialCells); + auto size = cellBounds.size() * sizeof(ivec4); + if (size > _cellBoundsBuffer->getSize()) { + _cellBoundsBuffer->resize(size); + } + _cellBoundsBuffer->setSubData(0, cellBounds); + batch.setInputBuffer(0, _cellBoundsBuffer, 0, sizeof(ivec4)); + batch.drawInstanced(cellBounds.size(), gpu::LINES, 24); // Draw the LOD Reticle { diff --git a/libraries/render/src/render/DrawSceneOctree.h b/libraries/render/src/render/DrawSceneOctree.h index 0b2cd6f685..3f7c07ded3 100644 --- a/libraries/render/src/render/DrawSceneOctree.h +++ b/libraries/render/src/render/DrawSceneOctree.h @@ -54,6 +54,8 @@ namespace render { gpu::PipelinePointer _drawCellBoundsPipeline; gpu::PipelinePointer _drawLODReticlePipeline; gpu::PipelinePointer _drawItemBoundPipeline; + gpu::BufferPointer _cellBoundsBuffer; + gpu::Stream::FormatPointer _cellBoundsFormat; bool _showVisibleCells; // initialized by Config bool _showEmptyCells; // initialized by Config diff --git a/libraries/render/src/render/drawCellBounds.slv b/libraries/render/src/render/drawCellBounds.slv index f3cc4c6411..913a3a372a 100644 --- a/libraries/render/src/render/drawCellBounds.slv +++ b/libraries/render/src/render/drawCellBounds.slv @@ -20,8 +20,7 @@ <$declareColorWheel()$> <@include SceneOctree.slh@> -layout(location=GPU_UNIFORM_EXTRA0) uniform ivec4 inCellLocation; - +layout(location=0) in ivec4 inCellLocation; layout(location=0) out vec4 varColor; void main(void) { From cafd981744e2bc246b647713ab71113e30189935 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 23 Aug 2018 16:17:55 -0700 Subject: [PATCH 293/545] Remove uniforms from bloom debug effect --- .../gpu/src/gpu/DrawTexcoordRectTransformUnitQuad.slv | 10 ++++++++-- libraries/render-utils/src/BloomEffect.cpp | 7 +++++-- libraries/render-utils/src/BloomEffect.h | 1 + 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/libraries/gpu/src/gpu/DrawTexcoordRectTransformUnitQuad.slv b/libraries/gpu/src/gpu/DrawTexcoordRectTransformUnitQuad.slv index d401fc40c2..8849cb494a 100755 --- a/libraries/gpu/src/gpu/DrawTexcoordRectTransformUnitQuad.slv +++ b/libraries/gpu/src/gpu/DrawTexcoordRectTransformUnitQuad.slv @@ -21,7 +21,13 @@ <$declareStandardTransform()$> -layout(location=GPU_UNIFORM_TEXCOORD_RECT) uniform vec4 texcoordRect; +struct TexCoordRectParams { + vec4 texcoordRect; +}; + +layout(binding=0) uniform texcoordRectBuffer { + TexCoordRectParams params; +}; layout(location=0) out vec2 varTexCoord0; @@ -39,5 +45,5 @@ void main(void) { TransformObject obj = getTransformObject(); <$transformModelToClipPos(cam, obj, pos, gl_Position)$> - varTexCoord0 = ((pos.xy + 1.0) * 0.5) * texcoordRect.zw + texcoordRect.xy; + varTexCoord0 = ((pos.xy + 1.0) * 0.5) * params.texcoordRect.zw + params.texcoordRect.xy; } diff --git a/libraries/render-utils/src/BloomEffect.cpp b/libraries/render-utils/src/BloomEffect.cpp index 3a35e736a9..e6217eb825 100644 --- a/libraries/render-utils/src/BloomEffect.cpp +++ b/libraries/render-utils/src/BloomEffect.cpp @@ -184,6 +184,7 @@ void BloomDraw::run(const render::RenderContextPointer& renderContext, const Inp } DebugBloom::DebugBloom() { + _params = std::make_shared(sizeof(glm::vec4), nullptr); } void DebugBloom::configure(const Config& config) { @@ -227,7 +228,8 @@ void DebugBloom::run(const render::RenderContextPointer& renderContext, const In Transform modelTransform; if (_mode == DebugBloomConfig::MODE_ALL_LEVELS) { - batch._glUniform4f(gpu::slot::uniform::TexCoordRect, 0.0f, 0.0f, 1.f, 1.f); + _params->setSubData(0, vec4(0.0f, 0.0f, 1.f, 1.f)); + batch.setUniformBuffer(0, _params); modelTransform = gpu::Framebuffer::evalSubregionTexcoordTransform(framebufferSize, args->_viewport / 2); modelTransform.postTranslate(glm::vec3(-1.0f, 1.0f, 0.0f)); @@ -255,7 +257,8 @@ void DebugBloom::run(const render::RenderContextPointer& renderContext, const In viewport.z /= 2; - batch._glUniform4f(gpu::slot::uniform::TexCoordRect, 0.5f, 0.0f, 0.5f, 1.f); + _params->setSubData(0, vec4(0.5f, 0.0f, 0.5f, 1.f)); + batch.setUniformBuffer(0, _params); modelTransform = gpu::Framebuffer::evalSubregionTexcoordTransform(framebufferSize, viewport); modelTransform.postTranslate(glm::vec3(-1.0f, 0.0f, 0.0f)); diff --git a/libraries/render-utils/src/BloomEffect.h b/libraries/render-utils/src/BloomEffect.h index 7789c70190..12c94bb929 100644 --- a/libraries/render-utils/src/BloomEffect.h +++ b/libraries/render-utils/src/BloomEffect.h @@ -121,6 +121,7 @@ public: private: gpu::PipelinePointer _pipeline; + gpu::BufferPointer _params; DebugBloomConfig::Mode _mode; }; From 5a5e1ad4989ed9e544bc5e62fb61bca5a4a82613 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 23 Aug 2018 16:18:10 -0700 Subject: [PATCH 294/545] Remove uniforms from polyvox --- .../src/RenderablePolyVoxEntityItem.cpp | 8 +++++++- .../src/RenderablePolyVoxEntityItem.h | 1 + .../src/entities-renderer/ShaderConstants.h | 12 ------------ libraries/entities-renderer/src/polyvox.slf | 15 +++++++++++---- libraries/entities-renderer/src/polyvox_fade.slf | 14 ++++++++++---- 5 files changed, 29 insertions(+), 21 deletions(-) diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index 2da5c30dc0..292b6368bb 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -1609,6 +1609,7 @@ PolyVoxEntityRenderer::PolyVoxEntityRenderer(const EntityItemPointer& entity) : _vertexFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0); _vertexFormat->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 12); }); + _params = std::make_shared(sizeof(glm::vec3), nullptr); } ShapeKey PolyVoxEntityRenderer::getShapeKey() { @@ -1671,9 +1672,12 @@ void PolyVoxEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& s void PolyVoxEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { _lastVoxelToWorldMatrix = entity->voxelToWorldMatrix(); + _lastVoxelVolumeSize = entity->getVoxelVolumeSize(); + _params->setSubData(0, _lastVoxelVolumeSize); graphics::MeshPointer newMesh; entity->withReadLock([&] { newMesh = entity->_mesh; + }); if (newMesh && newMesh->getIndexBuffer()._buffer) { @@ -1686,6 +1690,7 @@ void PolyVoxEntityRenderer::doRender(RenderArgs* args) { return; } + PerformanceTimer perfTimer("RenderablePolyVoxEntityItem::render"); gpu::Batch& batch = *args->_batch; @@ -1695,6 +1700,7 @@ void PolyVoxEntityRenderer::doRender(RenderArgs* args) { batch.setInputBuffer(gpu::Stream::POSITION, _mesh->getVertexBuffer()._buffer, 0, sizeof(PolyVox::PositionMaterialNormal)); + // TODO -- should we be setting this? // batch.setInputBuffer(gpu::Stream::NORMAL, mesh->getVertexBuffer()._buffer, // 12, @@ -1710,7 +1716,7 @@ void PolyVoxEntityRenderer::doRender(RenderArgs* args) { } } - batch._glUniform3f(entities_renderer::slot::uniform::PolyvoxVoxelSize, _lastVoxelVolumeSize.x, _lastVoxelVolumeSize.y, _lastVoxelVolumeSize.z); + batch.setUniformBuffer(0, _params); batch.drawIndexed(gpu::TRIANGLES, (gpu::uint32)_mesh->getNumIndices(), 0); } diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h index 7afb9b41b4..366a3fdc70 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h @@ -187,6 +187,7 @@ private: #endif graphics::MeshPointer _mesh; + gpu::BufferPointer _params; std::array _xyzTextures; glm::vec3 _lastVoxelVolumeSize; glm::mat4 _lastVoxelToWorldMatrix; diff --git a/libraries/entities-renderer/src/entities-renderer/ShaderConstants.h b/libraries/entities-renderer/src/entities-renderer/ShaderConstants.h index 58b0bf5688..d01075846a 100644 --- a/libraries/entities-renderer/src/entities-renderer/ShaderConstants.h +++ b/libraries/entities-renderer/src/entities-renderer/ShaderConstants.h @@ -15,7 +15,6 @@ #define ENTITIES_SHADER_CONSTANTS_H // Polyvox -#define ENTITIES_UNIFORM_POLYVOX_VOXEL_SIZE 0 #define ENTITIES_TEXTURE_POLYVOX_XMAP 0 #define ENTITIES_TEXTURE_POLYVOX_YMAP 1 #define ENTITIES_TEXTURE_POLYVOX_ZMAP 2 @@ -26,17 +25,6 @@ namespace entities_renderer { namespace slot { -namespace uniform { -enum Uniform { - PolyvoxVoxelSize = ENTITIES_UNIFORM_POLYVOX_VOXEL_SIZE, -}; -} - -namespace buffer { -enum Buffer { -}; -} // namespace buffer - namespace texture { enum Texture { PolyvoxXMap = ENTITIES_TEXTURE_POLYVOX_XMAP, diff --git a/libraries/entities-renderer/src/polyvox.slf b/libraries/entities-renderer/src/polyvox.slf index ba2fd7031b..e45bdc1a6b 100644 --- a/libraries/entities-renderer/src/polyvox.slf +++ b/libraries/entities-renderer/src/polyvox.slf @@ -23,15 +23,22 @@ layout(location=RENDER_UTILS_ATTR_POSITION_WS) in vec4 _worldPosition; layout(binding=ENTITIES_TEXTURE_POLYVOX_XMAP) uniform sampler2D xMap; layout(binding=ENTITIES_TEXTURE_POLYVOX_YMAP) uniform sampler2D yMap; layout(binding=ENTITIES_TEXTURE_POLYVOX_ZMAP) uniform sampler2D zMap; -layout(location=ENTITIES_UNIFORM_POLYVOX_VOXEL_SIZE) uniform vec3 voxelVolumeSize; + +struct PolyvoxParams { + vec3 voxelVolumeSize; +}; + +layout(binding=0) uniform polyvoxParamsBuffer { + PolyvoxParams params; +}; void main(void) { vec3 worldNormal = cross(dFdy(_worldPosition.xyz), dFdx(_worldPosition.xyz)); worldNormal = normalize(worldNormal); - float inPositionX = (_worldPosition.x - 0.5) / voxelVolumeSize.x; - float inPositionY = (_worldPosition.y - 0.5) / voxelVolumeSize.y; - float inPositionZ = (_worldPosition.z - 0.5) / voxelVolumeSize.z; + float inPositionX = (_worldPosition.x - 0.5) / params.voxelVolumeSize.x; + float inPositionY = (_worldPosition.y - 0.5) / params.voxelVolumeSize.y; + float inPositionZ = (_worldPosition.z - 0.5) / params.voxelVolumeSize.z; vec4 xyDiffuse = texture(xMap, vec2(-inPositionX, -inPositionY)); vec4 xzDiffuse = texture(yMap, vec2(-inPositionX, inPositionZ)); diff --git a/libraries/entities-renderer/src/polyvox_fade.slf b/libraries/entities-renderer/src/polyvox_fade.slf index 2247e472ea..0914debb3c 100644 --- a/libraries/entities-renderer/src/polyvox_fade.slf +++ b/libraries/entities-renderer/src/polyvox_fade.slf @@ -27,7 +27,13 @@ layout(binding=ENTITIES_TEXTURE_POLYVOX_XMAP) uniform sampler2D xMap; layout(binding=ENTITIES_TEXTURE_POLYVOX_YMAP) uniform sampler2D yMap; layout(binding=ENTITIES_TEXTURE_POLYVOX_ZMAP) uniform sampler2D zMap; -layout(location=ENTITIES_UNIFORM_POLYVOX_VOXEL_SIZE) uniform vec3 voxelVolumeSize; +struct PolyvoxParams { + vec3 voxelVolumeSize; +}; + +layout(binding=0) uniform polyvoxParamsBuffer { + PolyvoxParams params; +}; // Declare after all samplers to prevent sampler location mix up with voxel shading (sampler locations are hardcoded in RenderablePolyVoxEntityItem) <$declareFadeFragment()$> @@ -42,9 +48,9 @@ void main(void) { vec3 worldNormal = cross(dFdy(_worldPosition.xyz), dFdx(_worldPosition.xyz)); worldNormal = normalize(worldNormal); - float inPositionX = (_worldPosition.x - 0.5) / voxelVolumeSize.x; - float inPositionY = (_worldPosition.y - 0.5) / voxelVolumeSize.y; - float inPositionZ = (_worldPosition.z - 0.5) / voxelVolumeSize.z; + float inPositionX = (_worldPosition.x - 0.5) / params.voxelVolumeSize.x; + float inPositionY = (_worldPosition.y - 0.5) / params.voxelVolumeSize.y; + float inPositionZ = (_worldPosition.z - 0.5) / params.voxelVolumeSize.z; vec4 xyDiffuse = texture(xMap, vec2(-inPositionX, -inPositionY)); vec4 xzDiffuse = texture(yMap, vec2(-inPositionX, inPositionZ)); From 271651737b88d22fbf49bced2956b893a0a0740e Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 23 Aug 2018 16:19:21 -0700 Subject: [PATCH 295/545] Cleanup gpu shader constants --- libraries/gpu/src/gpu/ShaderConstants.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libraries/gpu/src/gpu/ShaderConstants.h b/libraries/gpu/src/gpu/ShaderConstants.h index dc5879e7ad..13dfd1be9c 100644 --- a/libraries/gpu/src/gpu/ShaderConstants.h +++ b/libraries/gpu/src/gpu/ShaderConstants.h @@ -40,8 +40,6 @@ // OSX seems to have an issue using 14 as an attribute location for passing from the vertex to the fragment shader #define GPU_ATTR_V2F_STEREO_SIDE 8 -#define GPU_UNIFORM_COLOR 101 -#define GPU_UNIFORM_TEXCOORD_RECT 102 #define GPU_UNIFORM_EXTRA0 110 #define GPU_UNIFORM_EXTRA1 111 #define GPU_UNIFORM_EXTRA2 112 @@ -98,8 +96,6 @@ enum Attribute { namespace uniform { enum Uniform { - Color = GPU_UNIFORM_COLOR, - TexCoordRect = GPU_UNIFORM_TEXCOORD_RECT, Extra0 = GPU_UNIFORM_EXTRA0, Extra1 = GPU_UNIFORM_EXTRA1, Extra2 = GPU_UNIFORM_EXTRA2, From 07fba89f0f1ef3e03052a2c74167f589fa3c8777 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Fri, 24 Aug 2018 10:09:00 -0700 Subject: [PATCH 296/545] Remove uniforms from item status --- libraries/render/src/render/DrawStatus.cpp | 44 ++++++++++++++++--- libraries/render/src/render/DrawStatus.h | 2 + .../render/src/render/drawItemStatus.slv | 8 ++-- 3 files changed, 44 insertions(+), 10 deletions(-) diff --git a/libraries/render/src/render/DrawStatus.cpp b/libraries/render/src/render/DrawStatus.cpp index 9b7d4ace2b..4fdee74868 100644 --- a/libraries/render/src/render/DrawStatus.cpp +++ b/libraries/render/src/render/DrawStatus.cpp @@ -170,13 +170,45 @@ void DrawStatus::run(const RenderContextPointer& renderContext, const Input& inp batch.setPipeline(getDrawItemStatusPipeline()); if (_showNetwork) { - for (size_t i = 0; i < itemBounds.size(); i++) { - batch._glUniform3fv(gpu::slot::uniform::Extra0, 1, (const float*)&itemBounds[i].bound.getCorner()); - batch._glUniform3fv(gpu::slot::uniform::Extra1, 1, ((const float*)&itemBounds[i].bound.getScale())); - batch._glUniform4iv(gpu::slot::uniform::Extra2, 1, (const int*)&(itemStatus[i].first)); - batch._glUniform4iv(gpu::slot::uniform::Extra3, 1, (const int*)&(itemStatus[i].second)); - batch.draw(gpu::TRIANGLES, 24 * NUM_STATUS_VEC4_PER_ITEM, 0); + if (!_instanceBuffer) { + _instanceBuffer = std::make_shared(); } + + struct InstanceData { + vec4 boundPos; + vec4 boundDim; + ivec4 status0; + ivec4 status1; + }; + + if (!_vertexFormat) { + _vertexFormat = std::make_shared(); + _vertexFormat->setAttribute(0, 0, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::XYZW), offsetof(InstanceData, boundPos), gpu::Stream::PER_INSTANCE); + _vertexFormat->setAttribute(1, 0, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::XYZW), offsetof(InstanceData, boundDim), gpu::Stream::PER_INSTANCE); + _vertexFormat->setAttribute(2, 0, gpu::Element(gpu::VEC4, gpu::INT32, gpu::XYZW), offsetof(InstanceData, status0), gpu::Stream::PER_INSTANCE); + _vertexFormat->setAttribute(3, 0, gpu::Element(gpu::VEC4, gpu::INT32, gpu::XYZW), offsetof(InstanceData, status1), gpu::Stream::PER_INSTANCE); + } + + batch.setInputFormat(_vertexFormat); + std::vector instanceData; + instanceData.resize(itemBounds.size()); + for (size_t i = 0; i < itemBounds.size(); i++) { + InstanceData& item = instanceData[i]; + const auto& bound = itemBounds[i].bound; + const auto& status = itemStatus[i]; + item.boundPos = vec4(bound.getCorner(), 1.0f); + item.boundDim = vec4(bound.getScale(), 1.0f); + item.status0 = status.first; + item.status1 = status.second; + } + + auto instanceBufferSize = sizeof(InstanceData) * instanceData.size(); + if (_instanceBuffer->getSize() < instanceBufferSize) { + _instanceBuffer->resize(instanceBufferSize); + } + _instanceBuffer->setSubData(0, instanceData); + batch.setInputBuffer(0, _instanceBuffer, 0, sizeof(InstanceData)); + batch.drawInstanced(instanceData.size(), gpu::TRIANGLES, 24 * NUM_STATUS_VEC4_PER_ITEM); } batch.setResourceTexture(0, 0); }); diff --git a/libraries/render/src/render/DrawStatus.h b/libraries/render/src/render/DrawStatus.h index 96269fda4d..2959ca59c5 100644 --- a/libraries/render/src/render/DrawStatus.h +++ b/libraries/render/src/render/DrawStatus.h @@ -63,6 +63,8 @@ namespace render { gpu::PipelinePointer _drawItemStatusPipeline; gpu::BufferPointer _boundsBuffer; + gpu::BufferPointer _instanceBuffer; + gpu::Stream::FormatPointer _vertexFormat; gpu::TexturePointer _statusIconMap; }; } diff --git a/libraries/render/src/render/drawItemStatus.slv b/libraries/render/src/render/drawItemStatus.slv index e92bdda248..7aac26fe2e 100644 --- a/libraries/render/src/render/drawItemStatus.slv +++ b/libraries/render/src/render/drawItemStatus.slv @@ -20,10 +20,10 @@ layout(location=0) out vec4 varColor; layout(location=1) out vec3 varTexcoord; -layout(location=GPU_UNIFORM_EXTRA0) uniform vec3 inBoundPos; -layout(location=GPU_UNIFORM_EXTRA1) uniform vec3 inBoundDim; -layout(location=GPU_UNIFORM_EXTRA2) uniform ivec4 inStatus0; -layout(location=GPU_UNIFORM_EXTRA3) uniform ivec4 inStatus1; +layout(location=0) in vec3 inBoundPos; +layout(location=1) in vec3 inBoundDim; +layout(location=2) in ivec4 inStatus0; +layout(location=3) in ivec4 inStatus1; vec3 paintRainbow(float normalizedHue) { float v = normalizedHue * 6.f; From a4cd56532e1666c5b30cd15f07e8b4c48382300e Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Fri, 24 Aug 2018 10:35:51 -0700 Subject: [PATCH 297/545] Removing uniforms from antialiasing --- .../render-utils/src/AntialiasingEffect.cpp | 103 ++++++------------ .../render-utils/src/AntialiasingEffect.h | 15 +-- libraries/render-utils/src/fxaa_blend.slf | 11 +- 3 files changed, 53 insertions(+), 76 deletions(-) diff --git a/libraries/render-utils/src/AntialiasingEffect.cpp b/libraries/render-utils/src/AntialiasingEffect.cpp index 2b17ba3c01..b3a645caed 100644 --- a/libraries/render-utils/src/AntialiasingEffect.cpp +++ b/libraries/render-utils/src/AntialiasingEffect.cpp @@ -29,7 +29,6 @@ namespace ru { - using render_utils::slot::uniform::Uniform; using render_utils::slot::texture::Texture; using render_utils::slot::buffer::Buffer; } @@ -39,13 +38,7 @@ namespace gr { using graphics::slot::buffer::Buffer; } -#define ANTIALIASING_USE_TAA 1 - #if !ANTIALIASING_USE_TAA -#include "fxaa_vert.h" -#include "fxaa_frag.h" -#include "fxaa_blend_frag.h" - Antialiasing::Antialiasing() { _geometryId = DependencyManager::get()->allocateID(); @@ -58,30 +51,9 @@ Antialiasing::~Antialiasing() { } } -const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline(RenderArgs* args) { - int width = args->_viewport.z; - int height = args->_viewport.w; - - if (_antialiasingBuffer && _antialiasingBuffer->getSize() != uvec2(width, height)) { - _antialiasingBuffer.reset(); - } - - if (!_antialiasingBuffer) { - // Link the antialiasing FBO to texture - _antialiasingBuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("antialiasing")); - auto format = gpu::Element::COLOR_SRGBA_32; - auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT); - _antialiasingTexture = gpu::Texture::createRenderBuffer(format, width, height, gpu::Texture::SINGLE_MIP, defaultSampler); - _antialiasingBuffer->setRenderBuffer(0, _antialiasingTexture); - } - +const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline() { if (!_antialiasingPipeline) { - auto vs = fxaa_vert::getShader(); - auto ps = fxaa_frag::getShader(); - gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps); - - _texcoordOffsetLoc = program->getUniforms().findLocation("texcoordOffset"); - + gpu::ShaderPointer program = gpu::Shader::createProgram(shader::render_utils::program::fxaa); gpu::StatePointer state = gpu::StatePointer(new gpu::State()); state->setDepthTest(false, false, gpu::LESS_EQUAL); @@ -96,9 +68,7 @@ const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline(RenderArgs* ar const gpu::PipelinePointer& Antialiasing::getBlendPipeline() { if (!_blendPipeline) { - auto vs = fxaa_vert::getShader(); - auto ps = fxaa_blend_frag::getShader(); - gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps); + gpu::ShaderPointer program = gpu::Shader::createProgram(shader::render_utils::program::fxaa_blend); gpu::StatePointer state = gpu::StatePointer(new gpu::State()); state->setDepthTest(false, false, gpu::LESS_EQUAL); PrepareStencil::testNoAA(*state); @@ -119,13 +89,30 @@ void Antialiasing::run(const render::RenderContextPointer& renderContext, const batch.enableStereo(false); batch.setViewportTransform(args->_viewport); - // FIXME: NEED to simplify that code to avoid all the GeometryCahce call, this is purely pixel manipulation - float fbWidth = renderContext->args->_viewport.z; - float fbHeight = renderContext->args->_viewport.w; - // float sMin = args->_viewport.x / fbWidth; - // float sWidth = args->_viewport.z / fbWidth; - // float tMin = args->_viewport.y / fbHeight; - // float tHeight = args->_viewport.w / fbHeight; + if (!_paramsBuffer) { + _paramsBuffer = std::make_shared(sizeof(glm::vec2), nullptr); + } + + { + int width = args->_viewport.z; + int height = args->_viewport.w; + if (_antialiasingBuffer && _antialiasingBuffer->getSize() != uvec2(width, height)) { + _antialiasingBuffer.reset(); + } + + if (!_antialiasingBuffer) { + // Link the antialiasing FBO to texture + _antialiasingBuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("antialiasing")); + auto format = gpu::Element::COLOR_SRGBA_32; + auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT); + _antialiasingTexture = gpu::Texture::createRenderBuffer(format, width, height, gpu::Texture::SINGLE_MIP, defaultSampler); + _antialiasingBuffer->setRenderBuffer(0, _antialiasingTexture); + glm::vec2 fbExtent { args->_viewport.z, args->_viewport.w }; + glm::vec2 inverseFbExtent = 1.0f / fbExtent; + _paramsBuffer->setSubData(0, inverseFbExtent); + } + } + glm::mat4 projMat; Transform viewMat; @@ -136,40 +123,18 @@ void Antialiasing::run(const render::RenderContextPointer& renderContext, const batch.setModelTransform(Transform()); // FXAA step - auto pipeline = getAntialiasingPipeline(renderContext->args); + auto pipeline = getAntialiasingPipeline(); batch.setResourceTexture(0, sourceBuffer->getRenderBuffer(0)); batch.setFramebuffer(_antialiasingBuffer); batch.setPipeline(pipeline); - - // initialize the view-space unpacking uniforms using frustum data - float left, right, bottom, top, nearVal, farVal; - glm::vec4 nearClipPlane, farClipPlane; - - args->getViewFrustum().computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); - - // float depthScale = (farVal - nearVal) / farVal; - // float nearScale = -1.0f / nearVal; - // float depthTexCoordScaleS = (right - left) * nearScale / sWidth; - // float depthTexCoordScaleT = (top - bottom) * nearScale / tHeight; - // float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS; - // float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT; - - batch._glUniform2f(_texcoordOffsetLoc, 1.0f / fbWidth, 1.0f / fbHeight); - - glm::vec4 color(0.0f, 0.0f, 0.0f, 1.0f); - glm::vec2 bottomLeft(-1.0f, -1.0f); - glm::vec2 topRight(1.0f, 1.0f); - glm::vec2 texCoordTopLeft(0.0f, 0.0f); - glm::vec2 texCoordBottomRight(1.0f, 1.0f); - DependencyManager::get()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color, _geometryId); - + batch.setUniformBuffer(0, _paramsBuffer); + batch.draw(gpu::TRIANGLE_STRIP, 4); // Blend step batch.setResourceTexture(0, _antialiasingTexture); batch.setFramebuffer(sourceBuffer); batch.setPipeline(getBlendPipeline()); - - DependencyManager::get()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color, _geometryId); + batch.draw(gpu::TRIANGLE_STRIP, 4); }); } #else @@ -314,7 +279,11 @@ void Antialiasing::run(const render::RenderContextPointer& renderContext, const // Must match the bindg point in the fxaa_blend.slf shader batch.setResourceFramebufferSwapChainTexture(0, _antialiasingBuffers, 1); // Disable sharpen if FXAA - batch._glUniform1f(ru::Uniform::TaaSharpenIntensity, _sharpen * _params.get().regionInfo.z); + if (!_blendParamsBuffer) { + _blendParamsBuffer = std::make_shared(sizeof(float), nullptr); + } + _blendParamsBuffer->setSubData(0, _sharpen * _params.get().regionInfo.z); + batch.setUniformBuffer(0, _blendParamsBuffer); } batch.draw(gpu::TRIANGLE_STRIP, 4); batch.advance(_antialiasingBuffers); diff --git a/libraries/render-utils/src/AntialiasingEffect.h b/libraries/render-utils/src/AntialiasingEffect.h index 61da352154..936ade043d 100644 --- a/libraries/render-utils/src/AntialiasingEffect.h +++ b/libraries/render-utils/src/AntialiasingEffect.h @@ -134,6 +134,10 @@ signals: #define SET_BIT(bitfield, bitIndex, value) bitfield = ((bitfield) & ~(1 << (bitIndex))) | ((value) << (bitIndex)) #define GET_BIT(bitfield, bitIndex) ((bitfield) & (1 << (bitIndex))) +#define ANTIALIASING_USE_TAA 1 + +#if ANTIALIASING_USE_TAA + struct TAAParams { float nope{ 0.0f }; float blend{ 0.15f }; @@ -186,7 +190,7 @@ private: gpu::FramebufferSwapChainPointer _antialiasingBuffers; gpu::TexturePointer _antialiasingTextures[2]; - + gpu::BufferPointer _blendParamsBuffer; gpu::PipelinePointer _antialiasingPipeline; gpu::PipelinePointer _blendPipeline; gpu::PipelinePointer _debugBlendPipeline; @@ -197,7 +201,7 @@ private: }; -/* +#else class AntiAliasingConfig : public render::Job::Config { Q_OBJECT Q_PROPERTY(bool enabled MEMBER enabled) @@ -219,18 +223,15 @@ public: const gpu::PipelinePointer& getBlendPipeline(); private: - - // Uniforms for AA - gpu::int32 _texcoordOffsetLoc; - gpu::FramebufferPointer _antialiasingBuffer; gpu::TexturePointer _antialiasingTexture; + gpu::BufferPointer _paramsBuffer; gpu::PipelinePointer _antialiasingPipeline; gpu::PipelinePointer _blendPipeline; int _geometryId { 0 }; }; -*/ +#endif #endif // hifi_AntialiasingEffect_h diff --git a/libraries/render-utils/src/fxaa_blend.slf b/libraries/render-utils/src/fxaa_blend.slf index aca050f047..b2515ccd7f 100644 --- a/libraries/render-utils/src/fxaa_blend.slf +++ b/libraries/render-utils/src/fxaa_blend.slf @@ -18,7 +18,14 @@ layout(location=0) in vec2 varTexCoord0; layout(location=0) out vec4 outFragColor; layout(binding=0) uniform sampler2D colorTexture; -layout(location=GPU_UNIFORM_EXTRA0) uniform float sharpenIntensity; + +struct FxaaBlendParams { + float sharpenIntensity; +}; + +layout(binding=0) uniform fxaaBlendParamsBuffer { + FxaaBlendParams params; +}; void main(void) { vec4 pixels[9]; @@ -39,5 +46,5 @@ void main(void) { vec4 minColor = max(vec4(0), pixels[4]-vec4(0.5)); vec4 maxColor = pixels[4]+vec4(0.5); - outFragColor = clamp(pixels[4] + sharpenedPixel * sharpenIntensity, minColor, maxColor); + outFragColor = clamp(pixels[4] + sharpenedPixel * params.sharpenIntensity, minColor, maxColor); } From f704ddc11c7a2a0542a46cb5047d140bf554a2f8 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Fri, 24 Aug 2018 23:25:36 -0700 Subject: [PATCH 298/545] Remove uniform from SDF text rendering --- libraries/render-utils/src/TextRenderer3D.cpp | 3 +- libraries/render-utils/src/TextRenderer3D.h | 4 +- libraries/render-utils/src/sdf_text3D.slf | 17 +++-- .../src/sdf_text3D_transparent.slf | 17 +++-- libraries/render-utils/src/text/Font.cpp | 70 +++++++++++-------- libraries/render-utils/src/text/Font.h | 34 +++++---- 6 files changed, 92 insertions(+), 53 deletions(-) diff --git a/libraries/render-utils/src/TextRenderer3D.cpp b/libraries/render-utils/src/TextRenderer3D.cpp index dd9167d248..8ef0dc0d73 100644 --- a/libraries/render-utils/src/TextRenderer3D.cpp +++ b/libraries/render-utils/src/TextRenderer3D.cpp @@ -70,9 +70,8 @@ void TextRenderer3D::draw(gpu::Batch& batch, float x, float y, const QString& st const glm::vec2& bounds, bool layered) { // The font does all the OpenGL work if (_font) { - // Cache color so that the pointer stays valid. _color = color; - _font->drawString(batch, x, y, str, &_color, _effectType, bounds, layered); + _font->drawString(batch, _drawInfo, str, _color, _effectType, { x, y }, bounds, layered); } } diff --git a/libraries/render-utils/src/TextRenderer3D.h b/libraries/render-utils/src/TextRenderer3D.h index 175802ef6e..6c91411e1d 100644 --- a/libraries/render-utils/src/TextRenderer3D.h +++ b/libraries/render-utils/src/TextRenderer3D.h @@ -15,12 +15,14 @@ #include #include #include +#include namespace gpu { class Batch; } class Font; +#include "text/Font.h" #include "text/EffectType.h" #include "text/FontFamilies.h" @@ -51,7 +53,7 @@ private: // text color glm::vec4 _color; - + Font::DrawInfo _drawInfo; std::shared_ptr _font; }; diff --git a/libraries/render-utils/src/sdf_text3D.slf b/libraries/render-utils/src/sdf_text3D.slf index 2fbaa03900..c002d0c262 100644 --- a/libraries/render-utils/src/sdf_text3D.slf +++ b/libraries/render-utils/src/sdf_text3D.slf @@ -14,8 +14,15 @@ <@include render-utils/ShaderConstants.h@> layout(binding=0) uniform sampler2D Font; -layout(location=RENDER_UTILS_UNIFORM_TEXT_OUTLINE) uniform bool Outline; -layout(location=RENDER_UTILS_UNIFORM_TEXT_COLOR) uniform vec4 Color; + +struct TextParams { + vec4 color; + float outline; +}; + +layout(binding=0) uniform textParamsBuffer { + TextParams params; +}; // the interpolated normal layout(location=RENDER_UTILS_ATTR_NORMAL_WS) in vec3 _normalWS; @@ -32,7 +39,7 @@ const float taaBias = pow(2.0, TAA_TEXTURE_LOD_BIAS); float evalSDF(vec2 texCoord) { // retrieve signed distance float sdf = textureLod(Font, texCoord, TAA_TEXTURE_LOD_BIAS).g; - if (Outline) { + if (params.outline > 0.0) { if (sdf > interiorCutoff) { sdf = 1.0 - sdf; } else { @@ -62,8 +69,8 @@ void main() { packDeferredFragment( normalize(_normalWS), - a * Color.a, - Color.rgb, + a * params.color.a, + params.color.rgb, DEFAULT_ROUGHNESS, DEFAULT_METALLIC, DEFAULT_EMISSIVE, diff --git a/libraries/render-utils/src/sdf_text3D_transparent.slf b/libraries/render-utils/src/sdf_text3D_transparent.slf index 218236c26b..d4c4fcc409 100644 --- a/libraries/render-utils/src/sdf_text3D_transparent.slf +++ b/libraries/render-utils/src/sdf_text3D_transparent.slf @@ -14,8 +14,15 @@ <@include render-utils/ShaderConstants.h@> layout(binding=0) uniform sampler2D Font; -layout(location=RENDER_UTILS_UNIFORM_TEXT_OUTLINE) uniform bool Outline; -layout(location=RENDER_UTILS_UNIFORM_TEXT_COLOR) uniform vec4 Color; + +struct TextParams { + vec4 color; + float outline; +}; + +layout(binding=0) uniform textParamsBuffer { + TextParams params; +}; // the interpolated normal layout(location=RENDER_UTILS_ATTR_NORMAL_WS) in vec3 _normalWS; @@ -31,7 +38,7 @@ const float outlineExpansion = 0.2; void main() { // retrieve signed distance float sdf = texture(Font, _texCoord0).g; - if (Outline) { + if (params.outline > 0.0) { if (sdf > interiorCutoff) { sdf = 1.0 - sdf; } else { @@ -51,8 +58,8 @@ void main() { packDeferredFragmentTranslucent( normalize(_normalWS), - a * Color.a, - Color.rgb, + a * params.color.a, + params.color.rgb, DEFAULT_FRESNEL, DEFAULT_ROUGHNESS); } \ No newline at end of file diff --git a/libraries/render-utils/src/text/Font.cpp b/libraries/render-utils/src/text/Font.cpp index aca6ddb79f..5ae50a8c73 100644 --- a/libraries/render-utils/src/text/Font.cpp +++ b/libraries/render-utils/src/text/Font.cpp @@ -256,29 +256,30 @@ void Font::setupGPU() { } } -void Font::rebuildVertices(float x, float y, const QString& str, const glm::vec2& bounds) { - _verticesBuffer = std::make_shared(); - _numVertices = 0; - _indicesBuffer = std::make_shared(); - _numIndices = 0; +void Font::buildVertices(Font::DrawInfo& drawInfo, const QString& str, const glm::vec2& origin, const glm::vec2& bounds) { + drawInfo.verticesBuffer = std::make_shared(); + drawInfo.indicesBuffer = std::make_shared(); + drawInfo.indexCount = 0; + int numVertices = 0; - _lastStringRendered = str; - _lastBounds = bounds; + drawInfo.string = str; + drawInfo.bounds = bounds; + drawInfo.origin = origin; // Top left of text - glm::vec2 advance = glm::vec2(x, y); + glm::vec2 advance = origin; foreach(const QString& token, tokenizeForWrapping(str)) { bool isNewLine = (token == QString('\n')); bool forceNewLine = false; // Handle wrapping - if (!isNewLine && (bounds.x != -1) && (advance.x + computeExtent(token).x > x + bounds.x)) { + if (!isNewLine && (bounds.x != -1) && (advance.x + computeExtent(token).x > origin.x + bounds.x)) { // We are out of the x bound, force new line forceNewLine = true; } if (isNewLine || forceNewLine) { // Character return, move the advance to a new line - advance = glm::vec2(x, advance.y - _leading); + advance = glm::vec2(origin.x, advance.y - _leading); if (isNewLine) { // No need to draw anything, go directly to next token @@ -288,7 +289,7 @@ void Font::rebuildVertices(float x, float y, const QString& str, const glm::vec2 break; } } - if ((bounds.y != -1) && (advance.y - _fontSize < -y - bounds.y)) { + if ((bounds.y != -1) && (advance.y - _fontSize < -origin.y - bounds.y)) { // We are out of the y bound, stop drawing break; } @@ -297,11 +298,11 @@ void Font::rebuildVertices(float x, float y, const QString& str, const glm::vec2 if (!isNewLine) { for (auto c : token) { auto glyph = _glyphs[c]; - quint16 verticesOffset = _numVertices; + quint16 verticesOffset = numVertices; QuadBuilder qd(glyph, advance - glm::vec2(0.0f, _ascent)); - _verticesBuffer->append(sizeof(QuadBuilder), (const gpu::Byte*)&qd); - _numVertices += 4; + drawInfo.verticesBuffer->append(qd); + numVertices += 4; // Sam's recommended triangle slices // Triangle tri1 = { v0, v1, v3 }; @@ -327,8 +328,8 @@ void Font::rebuildVertices(float x, float y, const QString& str, const glm::vec2 indices[3] = verticesOffset + 2; indices[4] = verticesOffset + 1; indices[5] = verticesOffset + 3; - _indicesBuffer->append(sizeof(indices), (const gpu::Byte*)indices); - _numIndices += NUMBER_OF_INDICES_PER_QUAD; + drawInfo.indicesBuffer->append(sizeof(indices), (const gpu::Byte*)indices); + drawInfo.indexCount += NUMBER_OF_INDICES_PER_QUAD; // Advance by glyph size @@ -341,26 +342,39 @@ void Font::rebuildVertices(float x, float y, const QString& str, const glm::vec2 } } -void Font::drawString(gpu::Batch& batch, float x, float y, const QString& str, const glm::vec4* color, - EffectType effectType, const glm::vec2& bounds, bool layered) { +void Font::drawString(gpu::Batch& batch, Font::DrawInfo& drawInfo, const QString& str, const glm::vec4& color, + EffectType effectType, const glm::vec2& origin, const glm::vec2& bounds, bool layered) { if (str == "") { return; } - if (str != _lastStringRendered || bounds != _lastBounds) { - rebuildVertices(x, y, str, bounds); + if (str != drawInfo.string || bounds != drawInfo.bounds || origin != drawInfo.origin) { + buildVertices(drawInfo, str, origin, bounds); } setupGPU(); - batch.setPipeline(((*color).a < 1.0f || layered) ? _transparentPipeline : _pipeline); - batch.setResourceTexture(render_utils::slot::texture::TextFont, _texture); - batch._glUniform1i(render_utils::slot::uniform::TextOutline, (effectType == OUTLINE_EFFECT)); + struct GpuDrawParams { + glm::vec4 color; + float outline; + }; + + if (!drawInfo.paramsBuffer || drawInfo.params.color != color || drawInfo.params.effect != effectType) { + drawInfo.params.color = color; + drawInfo.params.effect = effectType; + GpuDrawParams gpuDrawParams; + gpuDrawParams.color = ColorUtils::sRGBToLinearVec4(drawInfo.params.color); + gpuDrawParams.outline = (drawInfo.params.effect == OUTLINE_EFFECT) ? 1 : 0; + drawInfo.paramsBuffer = std::make_shared(sizeof(GpuDrawParams), nullptr); + drawInfo.paramsBuffer->setSubData(0, sizeof(GpuDrawParams), (const gpu::Byte*)&gpuDrawParams); + } // need the gamma corrected color here - glm::vec4 lrgba = ColorUtils::sRGBToLinearVec4(*color); - batch._glUniform4fv(render_utils::slot::uniform::TextColor, 1, (const float*)&lrgba); + + batch.setPipeline((color.a < 1.0f || layered) ? _transparentPipeline : _pipeline); batch.setInputFormat(_format); - batch.setInputBuffer(0, _verticesBuffer, 0, _format->getChannels().at(0)._stride); - batch.setIndexBuffer(gpu::UINT16, _indicesBuffer, 0); - batch.drawIndexed(gpu::TRIANGLES, _numIndices, 0); + batch.setInputBuffer(0, drawInfo.verticesBuffer, 0, _format->getChannels().at(0)._stride); + batch.setResourceTexture(render_utils::slot::texture::TextFont, _texture); + batch.setUniformBuffer(0, drawInfo.paramsBuffer, 0, sizeof(GpuDrawParams)); + batch.setIndexBuffer(gpu::UINT16, drawInfo.indicesBuffer, 0); + batch.drawIndexed(gpu::TRIANGLES, drawInfo.indexCount, 0); } diff --git a/libraries/render-utils/src/text/Font.h b/libraries/render-utils/src/text/Font.h index 2fa2b65fa5..9a0a9b4734 100644 --- a/libraries/render-utils/src/text/Font.h +++ b/libraries/render-utils/src/text/Font.h @@ -23,16 +23,34 @@ public: void read(QIODevice& path); + struct DrawParams { + vec4 color{ -1 }; + EffectType effect; + }; + + struct DrawInfo { + gpu::BufferPointer verticesBuffer; + gpu::BufferPointer indicesBuffer; + gpu::BufferPointer paramsBuffer; + uint32_t indexCount; + + QString string; + glm::vec2 origin; + glm::vec2 bounds; + DrawParams params; + }; + glm::vec2 computeExtent(const QString& str) const; float getFontSize() const { return _fontSize; } // Render string to batch - void drawString(gpu::Batch& batch, float x, float y, const QString& str, - const glm::vec4* color, EffectType effectType, - const glm::vec2& bound, bool layered = false); + void drawString(gpu::Batch& batch, DrawInfo& drawInfo, const QString& str, + const glm::vec4& color, EffectType effectType, + const glm::vec2& origin, const glm::vec2& bound, bool layered = false); static Pointer load(const QString& family); + private: static Pointer load(QIODevice& fontFile); QStringList tokenizeForWrapping(const QString& str) const; @@ -40,7 +58,7 @@ private: glm::vec2 computeTokenExtent(const QString& str) const; const Glyph& getGlyph(const QChar& c) const; - void rebuildVertices(float x, float y, const QString& str, const glm::vec2& bounds); + void buildVertices(DrawInfo& drawInfo, const QString& str, const glm::vec2& origin, const glm::vec2& bounds); void setupGPU(); @@ -66,15 +84,7 @@ private: gpu::PipelinePointer _transparentPipeline; gpu::TexturePointer _texture; gpu::Stream::FormatPointer _format; - gpu::BufferPointer _verticesBuffer; - gpu::BufferPointer _indicesBuffer; gpu::BufferStreamPointer _stream; - unsigned int _numVertices = 0; - unsigned int _numIndices = 0; - - // last string render characteristics - QString _lastStringRendered; - glm::vec2 _lastBounds; }; #endif From 730cdb4257f6543af89e1671cc5a1c97b4411e2f Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Fri, 24 Aug 2018 23:43:44 -0700 Subject: [PATCH 299/545] Remove uniforms from unused shaders --- libraries/render-utils/src/deferred_light_limited.slv | 3 ++- libraries/render-utils/src/fxaa.slf | 4 +++- .../render-utils/src/subsurfaceScattering_drawScattering.slf | 3 ++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/libraries/render-utils/src/deferred_light_limited.slv b/libraries/render-utils/src/deferred_light_limited.slv index fb59b8e78f..7aaec98e72 100644 --- a/libraries/render-utils/src/deferred_light_limited.slv +++ b/libraries/render-utils/src/deferred_light_limited.slv @@ -18,7 +18,8 @@ <$declareStandardTransform()$> -uniform vec4 sphereParam; +// FIXME make into a uniform buffer or push constant if this shader ever comes into use +vec4 sphereParam = vec4(0.0); layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord01; diff --git a/libraries/render-utils/src/fxaa.slf b/libraries/render-utils/src/fxaa.slf index 2dddcc795b..2c5e1cdc31 100644 --- a/libraries/render-utils/src/fxaa.slf +++ b/libraries/render-utils/src/fxaa.slf @@ -24,7 +24,9 @@ precision mediump int; layout(binding=0) uniform sampler2D colorTexture; //uniform sampler2D historyTexture; -layout(location=0) uniform vec2 texcoordOffset; + +// FIXME make into a uniform buffer or push constant if this shader ever comes into use +vec2 texcoordOffset = vec2(0.0); layout(location=0) in vec2 varTexCoord0; layout(location=0) out vec4 outFragColor; diff --git a/libraries/render-utils/src/subsurfaceScattering_drawScattering.slf b/libraries/render-utils/src/subsurfaceScattering_drawScattering.slf index 00b60d6fd4..9410a2ed2b 100644 --- a/libraries/render-utils/src/subsurfaceScattering_drawScattering.slf +++ b/libraries/render-utils/src/subsurfaceScattering_drawScattering.slf @@ -26,7 +26,8 @@ layout(location=0) in vec2 varTexCoord0; layout(location=0) out vec4 _fragColor; -layout(location=GPU_UNIFORM_EXTRA0) uniform vec2 uniformCursorTexcoord = vec2(0.5); +// FIXME make into a uniform buffer or push constant if this shader ever comes into use +vec2 uniformCursorTexcoord = vec2(0.5); //uniform vec3 uniformLightVector = vec3(1.0); From 87b9594bd0d97647c49fb77058b88996a44d3385 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Sat, 25 Aug 2018 09:54:06 -0700 Subject: [PATCH 300/545] Fix warnings --- libraries/render/src/render/DrawSceneOctree.cpp | 2 +- libraries/render/src/render/DrawStatus.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/render/src/render/DrawSceneOctree.cpp b/libraries/render/src/render/DrawSceneOctree.cpp index 60cfc64e27..6c87d2f56b 100644 --- a/libraries/render/src/render/DrawSceneOctree.cpp +++ b/libraries/render/src/render/DrawSceneOctree.cpp @@ -116,7 +116,7 @@ void DrawSceneOctree::run(const RenderContextPointer& renderContext, const ItemS } _cellBoundsBuffer->setSubData(0, cellBounds); batch.setInputBuffer(0, _cellBoundsBuffer, 0, sizeof(ivec4)); - batch.drawInstanced(cellBounds.size(), gpu::LINES, 24); + batch.drawInstanced((uint32_t)cellBounds.size(), gpu::LINES, 24); // Draw the LOD Reticle { diff --git a/libraries/render/src/render/DrawStatus.cpp b/libraries/render/src/render/DrawStatus.cpp index 4fdee74868..a1b61a4e77 100644 --- a/libraries/render/src/render/DrawStatus.cpp +++ b/libraries/render/src/render/DrawStatus.cpp @@ -208,7 +208,7 @@ void DrawStatus::run(const RenderContextPointer& renderContext, const Input& inp } _instanceBuffer->setSubData(0, instanceData); batch.setInputBuffer(0, _instanceBuffer, 0, sizeof(InstanceData)); - batch.drawInstanced(instanceData.size(), gpu::TRIANGLES, 24 * NUM_STATUS_VEC4_PER_ITEM); + batch.drawInstanced((uint32_t)instanceData.size(), gpu::TRIANGLES, 24 * NUM_STATUS_VEC4_PER_ITEM); } batch.setResourceTexture(0, 0); }); From 2df2bbef4662b0e5cd408504e7d793777b24deb6 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 28 Aug 2018 09:58:03 -0700 Subject: [PATCH 301/545] Adding missing locations --- libraries/render-utils/src/Highlight.slh | 4 ++-- libraries/render-utils/src/deferred_light_limited.slv | 4 ++-- libraries/render-utils/src/drawWorkloadProxy.slf | 6 +++--- libraries/render-utils/src/drawWorkloadProxy.slv | 6 +++--- libraries/render-utils/src/drawWorkloadView.slf | 6 +++--- libraries/render-utils/src/drawWorkloadView.slv | 6 +++--- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/libraries/render-utils/src/Highlight.slh b/libraries/render-utils/src/Highlight.slh index 56a999f508..9e988a6120 100644 --- a/libraries/render-utils/src/Highlight.slh +++ b/libraries/render-utils/src/Highlight.slh @@ -22,8 +22,8 @@ layout(binding=RENDER_UTILS_BUFFER_HIGHLIGHT_PARAMS) uniform highlightParamsBuff layout(binding=RENDER_UTILS_TEXTURE_HIGHLIGHT_SCENE_DEPTH) uniform sampler2D sceneDepthMap; layout(binding=RENDER_UTILS_TEXTURE_HIGHLIGHT_DEPTH) uniform sampler2D highlightedDepthMap; -in vec2 varTexCoord0; -out vec4 outFragColor; +layout(location=0) in vec2 varTexCoord0; +layout(location=0) out vec4 outFragColor; const float FAR_Z = 1.0; const float LINEAR_DEPTH_BIAS = 5e-3; diff --git a/libraries/render-utils/src/deferred_light_limited.slv b/libraries/render-utils/src/deferred_light_limited.slv index 7aaec98e72..1c835aacf7 100644 --- a/libraries/render-utils/src/deferred_light_limited.slv +++ b/libraries/render-utils/src/deferred_light_limited.slv @@ -42,7 +42,7 @@ void main(void) { } #endif #endif - _texCoord01.xy = vec4(projected.xy, 0.0, 1.0) * gl_Position.w; + _texCoord01 = vec4(projected.xy, 0.0, 1.0) * gl_Position.w; } else { const float depth = -1.0; //Draw at near plane const vec4 UNIT_QUAD[4] = vec4[4]( @@ -61,7 +61,7 @@ void main(void) { #endif #endif - _texCoord01.xy = vec4((pos.xy + 1.0) * 0.5, 0.0, 1.0); + _texCoord01 = vec4((pos.xy + 1.0) * 0.5, 0.0, 1.0); #ifdef GPU_TRANSFORM_IS_STEREO #ifdef GPU_TRANSFORM_STEREO_SPLIT_SCREEN diff --git a/libraries/render-utils/src/drawWorkloadProxy.slf b/libraries/render-utils/src/drawWorkloadProxy.slf index 32dceab00a..f0bd9d474c 100644 --- a/libraries/render-utils/src/drawWorkloadProxy.slf +++ b/libraries/render-utils/src/drawWorkloadProxy.slf @@ -13,9 +13,9 @@ <@include DeferredBufferWrite.slh@> <@include gpu/Paint.slh@> -in vec4 varColor; -in vec3 varTexcoord; -in vec3 varEyePos; +layout(location=0) in vec4 varColor; +layout(location=1) in vec3 varTexcoord; +layout(location=2) in vec3 varEyePos; void main(void) { if (varColor.w > 0.0) { diff --git a/libraries/render-utils/src/drawWorkloadProxy.slv b/libraries/render-utils/src/drawWorkloadProxy.slv index 28a62070f9..7a01702107 100644 --- a/libraries/render-utils/src/drawWorkloadProxy.slv +++ b/libraries/render-utils/src/drawWorkloadProxy.slv @@ -19,9 +19,9 @@ <$declareWorkloadProxies()$> -out vec4 varColor; -out vec3 varTexcoord; -out vec3 varEyePos; +layout(location=0) out vec4 varColor; +layout(location=1) out vec3 varTexcoord; +layout(location=2) out vec3 varEyePos; void main(void) { const vec4 UNIT_SPRITE[3] = vec4[3]( diff --git a/libraries/render-utils/src/drawWorkloadView.slf b/libraries/render-utils/src/drawWorkloadView.slf index c44dae4a24..b638824204 100644 --- a/libraries/render-utils/src/drawWorkloadView.slf +++ b/libraries/render-utils/src/drawWorkloadView.slf @@ -14,9 +14,9 @@ <@include DeferredBufferWrite.slh@> <@include gpu/Paint.slh@> -in vec4 varColor; -in vec3 varTexcoord; -in vec3 varEyePos; +layout(location=0) in vec4 varColor; +layout(location=1) in vec3 varTexcoord; +layout(location=2) in vec3 varEyePos; void main(void) { if (varColor.w > 0.0) { diff --git a/libraries/render-utils/src/drawWorkloadView.slv b/libraries/render-utils/src/drawWorkloadView.slv index 291a8c86cd..0e32c36e66 100644 --- a/libraries/render-utils/src/drawWorkloadView.slv +++ b/libraries/render-utils/src/drawWorkloadView.slv @@ -18,9 +18,9 @@ <@include WorkloadResource.slh@> <$declareWorkloadViews()$> -out vec4 varColor; -out vec3 varTexcoord; -out vec3 varEyePos; +layout(location=0) out vec4 varColor; +layout(location=1) out vec3 varTexcoord; +layout(location=2) out vec3 varEyePos; const int NUM_VERTICES_PER_SEGMENT = 2; const int NUM_SEGMENT_PER_VIEW_REGION = 65; From 9a28e04e37c3723da8f26f08dd6e9597246ce71a Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 28 Aug 2018 11:17:24 -0700 Subject: [PATCH 302/545] Remove all tabs from shaders --- libraries/gpu/src/gpu/Color.slh | 34 +-- libraries/gpu/src/gpu/Noise.slh | 14 +- .../gpu/src/gpu/TransformCamera_shared.slh | 4 +- .../src/BloomThreshold.shared.slh | 2 +- .../render-utils/src/DeferredBufferRead.slh | 2 +- .../render-utils/src/DeferredTransform.slh | 10 +- libraries/render-utils/src/Fade_shared.slh | 12 +- libraries/render-utils/src/Shadow.slh | 2 +- libraries/render-utils/src/ShadowCore.slh | 14 +- libraries/render-utils/src/Shadows_shared.slh | 4 +- .../src/debug_deferred_buffer_shared.slh | 2 +- libraries/render-utils/src/fxaa_blend.slf | 4 +- libraries/render-utils/src/glowLine.slf | 6 +- .../src/model_translucent_normal_map.slf | 2 +- .../src/model_translucent_normal_map_fade.slf | 2 +- libraries/render-utils/src/sdf_text3D.slf | 10 +- .../src/surfaceGeometry_copyDepth.slf | 4 +- libraries/render-utils/src/taa.slh | 250 +++++++++--------- libraries/render-utils/src/taa_blend.slf | 10 +- .../src/velocityBuffer_cameraMotion.slf | 6 +- .../render-utils/src/zone_drawKeyLight.slf | 4 +- .../render/src/render/drawItemStatus.slf | 2 +- 22 files changed, 200 insertions(+), 200 deletions(-) diff --git a/libraries/gpu/src/gpu/Color.slh b/libraries/gpu/src/gpu/Color.slh index 384b8bd329..16eb7487ed 100644 --- a/libraries/gpu/src/gpu/Color.slh +++ b/libraries/gpu/src/gpu/Color.slh @@ -31,29 +31,29 @@ vec4 color_sRGBAToLinear(vec4 srgba) { } vec3 color_LinearToYCoCg(vec3 rgb) { - // Y = R/4 + G/2 + B/4 - // Co = R/2 - B/2 - // Cg = -R/4 + G/2 - B/4 - return vec3( - rgb.x/4.0 + rgb.y/2.0 + rgb.z/4.0, - rgb.x/2.0 - rgb.z/2.0, - -rgb.x/4.0 + rgb.y/2.0 - rgb.z/4.0 - ); + // Y = R/4 + G/2 + B/4 + // Co = R/2 - B/2 + // Cg = -R/4 + G/2 - B/4 + return vec3( + rgb.x/4.0 + rgb.y/2.0 + rgb.z/4.0, + rgb.x/2.0 - rgb.z/2.0, + -rgb.x/4.0 + rgb.y/2.0 - rgb.z/4.0 + ); } vec3 color_YCoCgToUnclampedLinear(vec3 ycocg) { - // R = Y + Co - Cg - // G = Y + Cg - // B = Y - Co - Cg - return vec3( - ycocg.x + ycocg.y - ycocg.z, - ycocg.x + ycocg.z, - ycocg.x - ycocg.y - ycocg.z - ); + // R = Y + Co - Cg + // G = Y + Cg + // B = Y - Co - Cg + return vec3( + ycocg.x + ycocg.y - ycocg.z, + ycocg.x + ycocg.z, + ycocg.x - ycocg.y - ycocg.z + ); } vec3 color_YCoCgToLinear(vec3 ycocg) { - return clamp(color_YCoCgToUnclampedLinear(ycocg), vec3(0.0), vec3(1.0)); + return clamp(color_YCoCgToUnclampedLinear(ycocg), vec3(0.0), vec3(1.0)); } <@func declareColorWheel()@> diff --git a/libraries/gpu/src/gpu/Noise.slh b/libraries/gpu/src/gpu/Noise.slh index b390945957..d300e71ba9 100644 --- a/libraries/gpu/src/gpu/Noise.slh +++ b/libraries/gpu/src/gpu/Noise.slh @@ -284,14 +284,14 @@ float hifi_noise(in vec2 x) { // https://www.shadertoy.com/view/MdX3Rr // https://en.wikipedia.org/wiki/Fractional_Brownian_motion float hifi_fbm(in vec2 p) { - const mat2 m2 = mat2(0.8, -0.6, 0.6, 0.8); - float f = 0.0; - f += 0.5000 * hifi_noise(p); p = m2 * p * 2.02; - f += 0.2500 * hifi_noise(p); p = m2 * p * 2.03; - f += 0.1250 * hifi_noise(p); p = m2 * p * 2.01; - f += 0.0625 * hifi_noise(p); + const mat2 m2 = mat2(0.8, -0.6, 0.6, 0.8); + float f = 0.0; + f += 0.5000 * hifi_noise(p); p = m2 * p * 2.02; + f += 0.2500 * hifi_noise(p); p = m2 * p * 2.03; + f += 0.1250 * hifi_noise(p); p = m2 * p * 2.01; + f += 0.0625 * hifi_noise(p); - return f / 0.9375; + return f / 0.9375; } <@endif@> \ No newline at end of file diff --git a/libraries/gpu/src/gpu/TransformCamera_shared.slh b/libraries/gpu/src/gpu/TransformCamera_shared.slh index 37521d8201..e4a0f8c2cc 100644 --- a/libraries/gpu/src/gpu/TransformCamera_shared.slh +++ b/libraries/gpu/src/gpu/TransformCamera_shared.slh @@ -2,11 +2,11 @@ #ifdef __cplusplus # define _MAT4 Mat4 # define _VEC4 Vec4 -# define _MUTABLE mutable +# define _MUTABLE mutable #else # define _MAT4 mat4 # define _VEC4 vec4 -# define _MUTABLE +# define _MUTABLE #endif struct _TransformCamera { diff --git a/libraries/render-utils/src/BloomThreshold.shared.slh b/libraries/render-utils/src/BloomThreshold.shared.slh index 8aaf8ec311..5ad490a1ca 100644 --- a/libraries/render-utils/src/BloomThreshold.shared.slh +++ b/libraries/render-utils/src/BloomThreshold.shared.slh @@ -8,7 +8,7 @@ struct Parameters { BT_VEC2 _deltaUV; - float _threshold; + float _threshold; int _sampleCount; }; diff --git a/libraries/render-utils/src/DeferredBufferRead.slh b/libraries/render-utils/src/DeferredBufferRead.slh index 8c6c76b24a..e5a7c39d54 100644 --- a/libraries/render-utils/src/DeferredBufferRead.slh +++ b/libraries/render-utils/src/DeferredBufferRead.slh @@ -137,7 +137,7 @@ vec4 unpackDeferredPosition(float depthValue, vec2 texcoord) { // This method to unpack position is fastesst vec4 unpackDeferredPositionFromZdb(vec2 texcoord) { float Zdb = texture(depthMap, texcoord).x; - return unpackDeferredPosition(Zdb, texcoord); + return unpackDeferredPosition(Zdb, texcoord); } vec4 unpackDeferredPositionFromZeye(vec2 texcoord) { diff --git a/libraries/render-utils/src/DeferredTransform.slh b/libraries/render-utils/src/DeferredTransform.slh index 6dd92c651b..19986805f6 100644 --- a/libraries/render-utils/src/DeferredTransform.slh +++ b/libraries/render-utils/src/DeferredTransform.slh @@ -38,8 +38,8 @@ struct DeferredFrameTransform { mat4 _projectionMono; mat4 _viewInverse; mat4 _view; - mat4 _projectionUnJittered[2]; - mat4 _invProjectionUnJittered[2]; + mat4 _projectionUnJittered[2]; + mat4 _invProjectionUnJittered[2]; }; layout(binding=RENDER_UTILS_BUFFER_DEFERRED_FRAME_TRANSFORM) uniform deferredFrameTransformBuffer { @@ -68,10 +68,10 @@ mat4 getProjectionMono() { return frameTransform._projectionMono; } mat4 getUnjitteredProjection(int side) { - return frameTransform._projectionUnJittered[side]; + return frameTransform._projectionUnJittered[side]; } mat4 getUnjitteredInvProjection(int side) { - return frameTransform._invProjectionUnJittered[side]; + return frameTransform._invProjectionUnJittered[side]; } // positive near distance of the projection @@ -158,7 +158,7 @@ vec3 evalUnjitteredEyePositionFromZdb(int side, float Zdb, vec2 texcoord) { } vec3 evalEyePositionFromZeye(int side, float Zeye, vec2 texcoord) { - float Zdb = evalZdbFromZeye(Zeye); + float Zdb = evalZdbFromZeye(Zeye); return evalEyePositionFromZdb(side, Zdb, texcoord); } diff --git a/libraries/render-utils/src/Fade_shared.slh b/libraries/render-utils/src/Fade_shared.slh index 7d1c0fb8bc..7ede92b807 100644 --- a/libraries/render-utils/src/Fade_shared.slh +++ b/libraries/render-utils/src/Fade_shared.slh @@ -13,12 +13,12 @@ struct FadeParameters { - VEC4 _noiseInvSizeAndLevel; - VEC4 _innerEdgeColor; - VEC4 _outerEdgeColor; - VEC2 _edgeWidthInvWidth; - FLOAT32 _baseLevel; - INT32 _isInverted; + VEC4 _noiseInvSizeAndLevel; + VEC4 _innerEdgeColor; + VEC4 _outerEdgeColor; + VEC2 _edgeWidthInvWidth; + FLOAT32 _baseLevel; + INT32 _isInverted; }; // <@if 1@> diff --git a/libraries/render-utils/src/Shadow.slh b/libraries/render-utils/src/Shadow.slh index 85a30d5889..db1c3b4d85 100644 --- a/libraries/render-utils/src/Shadow.slh +++ b/libraries/render-utils/src/Shadow.slh @@ -45,7 +45,7 @@ struct ShadowSampleOffsets { }; ShadowSampleOffsets evalShadowFilterOffsets(vec4 position) { - float shadowScale = getShadowScale(); + float shadowScale = getShadowScale(); ShadowSampleOffsets offsets; #if SHADOW_SCREEN_SPACE_DITHER diff --git a/libraries/render-utils/src/ShadowCore.slh b/libraries/render-utils/src/ShadowCore.slh index 7d8eb9ab55..99c4b923f4 100644 --- a/libraries/render-utils/src/ShadowCore.slh +++ b/libraries/render-utils/src/ShadowCore.slh @@ -14,7 +14,7 @@ <@include Shadows_shared.slh@> layout(std140, binding=RENDER_UTILS_BUFFER_SHADOW_PARAMS) uniform shadowTransformBuffer { - ShadowParameters shadow; + ShadowParameters shadow; }; int getShadowCascadeCount() { @@ -30,26 +30,26 @@ float evalShadowFalloff(float depth) { } mat4 getShadowReprojection(int cascadeIndex) { - return shadow.cascades[cascadeIndex].reprojection; + return shadow.cascades[cascadeIndex].reprojection; } float getShadowScale() { - return shadow.invMapSize; + return shadow.invMapSize; } float getShadowFixedBias(int cascadeIndex) { - return shadow.cascades[cascadeIndex].fixedBias; + return shadow.cascades[cascadeIndex].fixedBias; } float getShadowSlopeBias(int cascadeIndex) { - return shadow.cascades[cascadeIndex].slopeBias; + return shadow.cascades[cascadeIndex].slopeBias; } // Compute the texture coordinates from world coordinates vec4 evalShadowTexcoord(int cascadeIndex, vec4 position) { - vec4 shadowCoord = getShadowReprojection(cascadeIndex) * position; - return vec4(shadowCoord.xyz, 1.0); + vec4 shadowCoord = getShadowReprojection(cascadeIndex) * position; + return vec4(shadowCoord.xyz, 1.0); } bool isShadowCascadeProjectedOnPixel(vec4 cascadeTexCoords) { diff --git a/libraries/render-utils/src/Shadows_shared.slh b/libraries/render-utils/src/Shadows_shared.slh index bc8063e018..9cb46587a2 100644 --- a/libraries/render-utils/src/Shadows_shared.slh +++ b/libraries/render-utils/src/Shadows_shared.slh @@ -8,8 +8,8 @@ #define SHADOW_CASCADE_MAX_COUNT 4 struct ShadowTransform { - MAT4 reprojection; - float fixedBias; + MAT4 reprojection; + float fixedBias; float slopeBias; float _padding1; float _padding2; diff --git a/libraries/render-utils/src/debug_deferred_buffer_shared.slh b/libraries/render-utils/src/debug_deferred_buffer_shared.slh index 2d11a66d61..f5d6797c50 100644 --- a/libraries/render-utils/src/debug_deferred_buffer_shared.slh +++ b/libraries/render-utils/src/debug_deferred_buffer_shared.slh @@ -7,7 +7,7 @@ struct DebugParameters { - INT32 _shadowCascadeIndex; + INT32 _shadowCascadeIndex; }; // <@if 1@> diff --git a/libraries/render-utils/src/fxaa_blend.slf b/libraries/render-utils/src/fxaa_blend.slf index b2515ccd7f..2b9db649ca 100644 --- a/libraries/render-utils/src/fxaa_blend.slf +++ b/libraries/render-utils/src/fxaa_blend.slf @@ -44,7 +44,7 @@ void main(void) { sharpenedPixel = pixels[4]*6.8 - (pixels[1]+pixels[3]+pixels[5]+pixels[7]) - (pixels[0]+pixels[2]+pixels[6]+pixels[8])*0.7; - vec4 minColor = max(vec4(0), pixels[4]-vec4(0.5)); - vec4 maxColor = pixels[4]+vec4(0.5); + vec4 minColor = max(vec4(0), pixels[4]-vec4(0.5)); + vec4 maxColor = pixels[4]+vec4(0.5); outFragColor = clamp(pixels[4] + sharpenedPixel * params.sharpenIntensity, minColor, maxColor); } diff --git a/libraries/render-utils/src/glowLine.slf b/libraries/render-utils/src/glowLine.slf index 4e80b3358a..c65d8d6488 100644 --- a/libraries/render-utils/src/glowLine.slf +++ b/libraries/render-utils/src/glowLine.slf @@ -22,9 +22,9 @@ void main(void) { float alpha = 1.0 - abs(distanceFromCenter); // Convert from a linear alpha curve to a sharp peaked one - alpha = _color.a * pow(alpha, 10.0); - - // Drop everything where the curve falls off to nearly nothing + alpha = _color.a * pow(alpha, 10.0); + + // Drop everything where the curve falls off to nearly nothing if (alpha <= 0.05) { discard; } diff --git a/libraries/render-utils/src/model_translucent_normal_map.slf b/libraries/render-utils/src/model_translucent_normal_map.slf index 45eee9d160..7ac6982cfa 100644 --- a/libraries/render-utils/src/model_translucent_normal_map.slf +++ b/libraries/render-utils/src/model_translucent_normal_map.slf @@ -87,7 +87,7 @@ void main(void) { 1.0, occlusionTex, fragPositionES, - fragPositionWS, + fragPositionWS, albedo, fresnel, metallic, diff --git a/libraries/render-utils/src/model_translucent_normal_map_fade.slf b/libraries/render-utils/src/model_translucent_normal_map_fade.slf index 2ede2bfbaa..2c182aeb19 100644 --- a/libraries/render-utils/src/model_translucent_normal_map_fade.slf +++ b/libraries/render-utils/src/model_translucent_normal_map_fade.slf @@ -97,7 +97,7 @@ void main(void) { 1.0, occlusionTex, fragPositionES, - fragPositionWS, + fragPositionWS, albedo, fresnel, metallic, diff --git a/libraries/render-utils/src/sdf_text3D.slf b/libraries/render-utils/src/sdf_text3D.slf index c002d0c262..0a177cb58f 100644 --- a/libraries/render-utils/src/sdf_text3D.slf +++ b/libraries/render-utils/src/sdf_text3D.slf @@ -54,12 +54,12 @@ void main() { vec2 dxTexCoord = dFdx(_texCoord0) * 0.5 * taaBias; vec2 dyTexCoord = dFdy(_texCoord0) * 0.5 * taaBias; - // Perform 4x supersampling for anisotropic filtering + // Perform 4x supersampling for anisotropic filtering float a; - a = evalSDF(_texCoord0); - a += evalSDF(_texCoord0+dxTexCoord); - a += evalSDF(_texCoord0+dyTexCoord); - a += evalSDF(_texCoord0+dxTexCoord+dyTexCoord); + a = evalSDF(_texCoord0); + a += evalSDF(_texCoord0+dxTexCoord); + a += evalSDF(_texCoord0+dyTexCoord); + a += evalSDF(_texCoord0+dxTexCoord+dyTexCoord); a *= 0.25; // discard if invisible diff --git a/libraries/render-utils/src/surfaceGeometry_copyDepth.slf b/libraries/render-utils/src/surfaceGeometry_copyDepth.slf index 7eb097224e..f018ee1105 100644 --- a/libraries/render-utils/src/surfaceGeometry_copyDepth.slf +++ b/libraries/render-utils/src/surfaceGeometry_copyDepth.slf @@ -16,7 +16,7 @@ layout(binding=0) uniform sampler2D depthMap; layout(location=0) out vec4 outFragColor; void main(void) { - float Zdb = texelFetch(depthMap, ivec2(gl_FragCoord.xy), 0).x; - outFragColor = vec4(Zdb, 0.0, 0.0, 1.0); + float Zdb = texelFetch(depthMap, ivec2(gl_FragCoord.xy), 0).x; + outFragColor = vec4(Zdb, 0.0, 0.0, 1.0); } diff --git a/libraries/render-utils/src/taa.slh b/libraries/render-utils/src/taa.slh index 26ffe55263..1692c33ef6 100644 --- a/libraries/render-utils/src/taa.slh +++ b/libraries/render-utils/src/taa.slh @@ -24,10 +24,10 @@ layout(binding=RENDER_UTILS_TEXTURE_TAA_NEXT) uniform sampler2D nextMap; struct TAAParams { - float none; - float blend; - float covarianceGamma; - float debugShowVelocityThreshold; + float none; + float blend; + float covarianceGamma; + float debugShowVelocityThreshold; ivec4 flags; vec4 pixelInfo_orbZoom; vec4 regionInfo; @@ -77,47 +77,47 @@ vec2 taa_getRegionFXAA() { #define USE_YCOCG 1 vec4 taa_fetchColor(sampler2D map, vec2 uv) { - vec4 c = texture(map, uv); - // Apply rapid pseudo tonemapping as TAA is applied to a tonemapped image, using luminance as weight, as proposed in - // https://de45xmedrsdbp.cloudfront.net/Resources/files/TemporalAA_small-59732822.pdf - float lum = dot(vec3(0.3,0.5,0.2),c.rgb); - c.rgb = c.rgb / (1.0+lum); + vec4 c = texture(map, uv); + // Apply rapid pseudo tonemapping as TAA is applied to a tonemapped image, using luminance as weight, as proposed in + // https://de45xmedrsdbp.cloudfront.net/Resources/files/TemporalAA_small-59732822.pdf + float lum = dot(vec3(0.3,0.5,0.2),c.rgb); + c.rgb = c.rgb / (1.0+lum); #if USE_YCOCG - return vec4(color_LinearToYCoCg(c.rgb), c.a); + return vec4(color_LinearToYCoCg(c.rgb), c.a); #else - return c; + return c; #endif } vec3 taa_resolveColor(vec3 color) { #if USE_YCOCG - color = max(vec3(0), color_YCoCgToUnclampedLinear(color)); + color = max(vec3(0), color_YCoCgToUnclampedLinear(color)); #endif - // Apply rapid inverse tonemapping, using luminance as weight, as proposed in - // https://de45xmedrsdbp.cloudfront.net/Resources/files/TemporalAA_small-59732822.pdf - float lum = dot(vec3(0.3,0.5,0.2),color.rgb); - color = color / (1.0-lum); - return color; + // Apply rapid inverse tonemapping, using luminance as weight, as proposed in + // https://de45xmedrsdbp.cloudfront.net/Resources/files/TemporalAA_small-59732822.pdf + float lum = dot(vec3(0.3,0.5,0.2),color.rgb); + color = color / (1.0-lum); + return color; } vec4 taa_fetchSourceMap(vec2 uv) { - return taa_fetchColor(sourceMap, uv); + return taa_fetchColor(sourceMap, uv); } vec4 taa_fetchHistoryMap(vec2 uv) { - return taa_fetchColor(historyMap, uv); + return taa_fetchColor(historyMap, uv); } vec4 taa_fetchNextMap(vec2 uv) { - return taa_fetchColor(nextMap, uv); + return taa_fetchColor(nextMap, uv); } vec2 taa_fetchVelocityMap(vec2 uv) { - return texture(velocityMap, uv).xy; + return texture(velocityMap, uv).xy; } float taa_fetchDepth(vec2 uv) { - return -texture(depthMap, vec2(uv), 0).x; + return -texture(depthMap, vec2(uv), 0).x; } @@ -141,35 +141,35 @@ vec2 taa_getTexelSize() { vec3 taa_findClosestFragment3x3(vec2 uv) { - vec2 dd = abs(taa_getTexelSize()); - vec2 du = vec2(dd.x, 0.0); - vec2 dv = vec2(0.0, dd.y); + vec2 dd = abs(taa_getTexelSize()); + vec2 du = vec2(dd.x, 0.0); + vec2 dv = vec2(0.0, dd.y); - vec3 dtl = vec3(-1, -1, taa_fetchDepth(uv - dv - du)); - vec3 dtc = vec3( 0, -1, taa_fetchDepth(uv - dv)); - vec3 dtr = vec3( 1, -1, taa_fetchDepth(uv - dv + du)); + vec3 dtl = vec3(-1, -1, taa_fetchDepth(uv - dv - du)); + vec3 dtc = vec3( 0, -1, taa_fetchDepth(uv - dv)); + vec3 dtr = vec3( 1, -1, taa_fetchDepth(uv - dv + du)); - vec3 dml = vec3(-1, 0, taa_fetchDepth(uv - du)); - vec3 dmc = vec3( 0, 0, taa_fetchDepth(uv)); - vec3 dmr = vec3( 1, 0, taa_fetchDepth(uv + du)); + vec3 dml = vec3(-1, 0, taa_fetchDepth(uv - du)); + vec3 dmc = vec3( 0, 0, taa_fetchDepth(uv)); + vec3 dmr = vec3( 1, 0, taa_fetchDepth(uv + du)); - vec3 dbl = vec3(-1, 1, taa_fetchDepth(uv + dv - du)); - vec3 dbc = vec3( 0, 1, taa_fetchDepth(uv + dv)); - vec3 dbr = vec3( 1, 1, taa_fetchDepth(uv + dv + du)); + vec3 dbl = vec3(-1, 1, taa_fetchDepth(uv + dv - du)); + vec3 dbc = vec3( 0, 1, taa_fetchDepth(uv + dv)); + vec3 dbr = vec3( 1, 1, taa_fetchDepth(uv + dv + du)); - vec3 dmin = dtl; - if (ZCMP_GT(dmin.z, dtc.z)) dmin = dtc; - if (ZCMP_GT(dmin.z, dtr.z)) dmin = dtr; + vec3 dmin = dtl; + if (ZCMP_GT(dmin.z, dtc.z)) dmin = dtc; + if (ZCMP_GT(dmin.z, dtr.z)) dmin = dtr; - if (ZCMP_GT(dmin.z, dml.z)) dmin = dml; - if (ZCMP_GT(dmin.z, dmc.z)) dmin = dmc; - if (ZCMP_GT(dmin.z, dmr.z)) dmin = dmr; + if (ZCMP_GT(dmin.z, dml.z)) dmin = dml; + if (ZCMP_GT(dmin.z, dmc.z)) dmin = dmc; + if (ZCMP_GT(dmin.z, dmr.z)) dmin = dmr; - if (ZCMP_GT(dmin.z, dbl.z)) dmin = dbl; - if (ZCMP_GT(dmin.z, dbc.z)) dmin = dbc; - if (ZCMP_GT(dmin.z, dbr.z)) dmin = dbr; + if (ZCMP_GT(dmin.z, dbl.z)) dmin = dbl; + if (ZCMP_GT(dmin.z, dbc.z)) dmin = dbc; + if (ZCMP_GT(dmin.z, dbr.z)) dmin = dbr; - return vec3(uv + dd.xy * dmin.xy, dmin.z); + return vec3(uv + dd.xy * dmin.xy, dmin.z); } vec2 taa_fetchVelocityMapBest(vec2 uv) { @@ -264,8 +264,8 @@ mat3 taa_evalNeighbourColorVariance(vec3 sourceColor, vec2 fragUV, vec2 fragVelo vec2 texelSize = taa_getTexelSize(); - vec2 du = vec2(texelSize.x, 0.0); - vec2 dv = vec2(0.0, texelSize.y); + vec2 du = vec2(texelSize.x, 0.0); + vec2 dv = vec2(0.0, texelSize.y); vec3 sampleColor = taa_fetchSourceMap(fragUV - dv - du).rgb; vec3 sumSamples = sampleColor; @@ -320,72 +320,72 @@ mat3 taa_evalNeighbourColorRegion(vec3 sourceColor, vec2 fragUV, vec2 fragVeloci vec3 cmin, cmax, cavg; #if MINMAX_3X3_ROUNDED - vec2 du = vec2(texelSize.x, 0.0); - vec2 dv = vec2(0.0, texelSize.y); + vec2 du = vec2(texelSize.x, 0.0); + vec2 dv = vec2(0.0, texelSize.y); - vec3 ctl = taa_fetchSourceMap(fragUV - dv - du).rgb; - vec3 ctc = taa_fetchSourceMap(fragUV - dv).rgb; - vec3 ctr = taa_fetchSourceMap(fragUV - dv + du).rgb; - vec3 cml = taa_fetchSourceMap(fragUV - du).rgb; - vec3 cmc = sourceColor; //taa_fetchSourceMap(fragUV).rgb; // could resuse the same osurce sample isn't it ? - vec3 cmr = taa_fetchSourceMap(fragUV + du).rgb; - vec3 cbl = taa_fetchSourceMap(fragUV + dv - du).rgb; - vec3 cbc = taa_fetchSourceMap(fragUV + dv).rgb; - vec3 cbr = taa_fetchSourceMap(fragUV + dv + du).rgb; + vec3 ctl = taa_fetchSourceMap(fragUV - dv - du).rgb; + vec3 ctc = taa_fetchSourceMap(fragUV - dv).rgb; + vec3 ctr = taa_fetchSourceMap(fragUV - dv + du).rgb; + vec3 cml = taa_fetchSourceMap(fragUV - du).rgb; + vec3 cmc = sourceColor; //taa_fetchSourceMap(fragUV).rgb; // could resuse the same osurce sample isn't it ? + vec3 cmr = taa_fetchSourceMap(fragUV + du).rgb; + vec3 cbl = taa_fetchSourceMap(fragUV + dv - du).rgb; + vec3 cbc = taa_fetchSourceMap(fragUV + dv).rgb; + vec3 cbr = taa_fetchSourceMap(fragUV + dv + du).rgb; - cmin = min(ctl, min(ctc, min(ctr, min(cml, min(cmc, min(cmr, min(cbl, min(cbc, cbr)))))))); - cmax = max(ctl, max(ctc, max(ctr, max(cml, max(cmc, max(cmr, max(cbl, max(cbc, cbr)))))))); + cmin = min(ctl, min(ctc, min(ctr, min(cml, min(cmc, min(cmr, min(cbl, min(cbc, cbr)))))))); + cmax = max(ctl, max(ctc, max(ctr, max(cml, max(cmc, max(cmr, max(cbl, max(cbc, cbr)))))))); - #if MINMAX_3X3_ROUNDED || USE_YCOCG || USE_CLIPPING - cavg = (ctl + ctc + ctr + cml + cmc + cmr + cbl + cbc + cbr) / 9.0; + #if MINMAX_3X3_ROUNDED || USE_YCOCG || USE_CLIPPING + cavg = (ctl + ctc + ctr + cml + cmc + cmr + cbl + cbc + cbr) / 9.0; #elif cavg = (cmin + cmax ) * 0.5; - #endif + #endif - #if MINMAX_3X3_ROUNDED - vec3 cmin5 = min(ctc, min(cml, min(cmc, min(cmr, cbc)))); - vec3 cmax5 = max(ctc, max(cml, max(cmc, max(cmr, cbc)))); - vec3 cavg5 = (ctc + cml + cmc + cmr + cbc) / 5.0; - cmin = 0.5 * (cmin + cmin5); - cmax = 0.5 * (cmax + cmax5); - cavg = 0.5 * (cavg + cavg5); - #endif + #if MINMAX_3X3_ROUNDED + vec3 cmin5 = min(ctc, min(cml, min(cmc, min(cmr, cbc)))); + vec3 cmax5 = max(ctc, max(cml, max(cmc, max(cmr, cbc)))); + vec3 cavg5 = (ctc + cml + cmc + cmr + cbc) / 5.0; + cmin = 0.5 * (cmin + cmin5); + cmax = 0.5 * (cmax + cmax5); + cavg = 0.5 * (cavg + cavg5); + #endif #else - const float _SubpixelThreshold = 0.5; - const float _GatherBase = 0.5; - const float _GatherSubpixelMotion = 0.1666; + const float _SubpixelThreshold = 0.5; + const float _GatherBase = 0.5; + const float _GatherSubpixelMotion = 0.1666; - vec2 texel_vel = fragVelocity * imageSize; - float texel_vel_mag = length(texel_vel) * -fragZe; - float k_subpixel_motion = clamp(_SubpixelThreshold / (0.0001 + texel_vel_mag), 0.0, 1.0); - float k_min_max_support = _GatherBase + _GatherSubpixelMotion * k_subpixel_motion; + vec2 texel_vel = fragVelocity * imageSize; + float texel_vel_mag = length(texel_vel) * -fragZe; + float k_subpixel_motion = clamp(_SubpixelThreshold / (0.0001 + texel_vel_mag), 0.0, 1.0); + float k_min_max_support = _GatherBase + _GatherSubpixelMotion * k_subpixel_motion; - vec2 ss_offset01 = k_min_max_support * vec2(-texelSize.x, texelSize.y); - vec2 ss_offset11 = k_min_max_support * vec2(texelSize.x, texelSize.y); - vec3 c00 = taa_fetchSourceMap(fragUV - ss_offset11).rgb; - vec3 c10 = taa_fetchSourceMap(fragUV - ss_offset01).rgb; - vec3 c01 = taa_fetchSourceMap(fragUV + ss_offset01).rgb; - vec3 c11 = taa_fetchSourceMap(fragUV + ss_offset11).rgb; + vec2 ss_offset01 = k_min_max_support * vec2(-texelSize.x, texelSize.y); + vec2 ss_offset11 = k_min_max_support * vec2(texelSize.x, texelSize.y); + vec3 c00 = taa_fetchSourceMap(fragUV - ss_offset11).rgb; + vec3 c10 = taa_fetchSourceMap(fragUV - ss_offset01).rgb; + vec3 c01 = taa_fetchSourceMap(fragUV + ss_offset01).rgb; + vec3 c11 = taa_fetchSourceMap(fragUV + ss_offset11).rgb; - cmin = min(c00, min(c10, min(c01, c11))); - cmax = max(c00, max(c10, max(c01, c11))); + cmin = min(c00, min(c10, min(c01, c11))); + cmax = max(c00, max(c10, max(c01, c11))); cavg = (cmin + cmax ) * 0.5; - #if USE_YCOCG || USE_CLIPPING - cavg = (c00 + c10 + c01 + c11) / 4.0; + #if USE_YCOCG || USE_CLIPPING + cavg = (c00 + c10 + c01 + c11) / 4.0; #elif cavg = (cmin + cmax ) * 0.5; - #endif + #endif #endif - // shrink chroma min-max - #if USE_YCOCG - vec2 chroma_extent = vec2(0.25 * 0.5 * (cmax.r - cmin.r)); - vec2 chroma_center = sourceColor.gb; - cmin.yz = chroma_center - chroma_extent; - cmax.yz = chroma_center + chroma_extent; - cavg.yz = chroma_center; - #endif + // shrink chroma min-max + #if USE_YCOCG + vec2 chroma_extent = vec2(0.25 * 0.5 * (cmax.r - cmin.r)); + vec2 chroma_center = sourceColor.gb; + cmin.yz = chroma_center - chroma_extent; + cmax.yz = chroma_center + chroma_extent; + cavg.yz = chroma_center; + #endif return mat3(cmin, cmax, cavg); } @@ -393,22 +393,22 @@ mat3 taa_evalNeighbourColorRegion(vec3 sourceColor, vec2 fragUV, vec2 fragVeloci //#define USE_OPTIMIZATIONS 0 vec3 taa_clampColor(vec3 colorMin, vec3 colorMax, vec3 colorSource, vec3 color) { - const float eps = 0.00001; + const float eps = 0.00001; vec3 p = colorSource; vec3 q = color; - // note: only clips towards aabb center (but fast!) - vec3 p_clip = 0.5 * (colorMax + colorMin); - vec3 e_clip = 0.5 * (colorMax - colorMin) + vec3(eps); + // note: only clips towards aabb center (but fast!) + vec3 p_clip = 0.5 * (colorMax + colorMin); + vec3 e_clip = 0.5 * (colorMax - colorMin) + vec3(eps); - vec3 v_clip = q - p_clip; - vec3 v_unit = v_clip.xyz / e_clip; - vec3 a_unit = abs(v_unit); - float ma_unit = max(a_unit.x, max(a_unit.y, a_unit.z)); + vec3 v_clip = q - p_clip; + vec3 v_unit = v_clip.xyz / e_clip; + vec3 a_unit = abs(v_unit); + float ma_unit = max(a_unit.x, max(a_unit.y, a_unit.z)); - if (ma_unit > 1.0) - return p_clip + v_clip / ma_unit; - else - return q;// point inside aabb + if (ma_unit > 1.0) + return p_clip + v_clip / ma_unit; + else + return q;// point inside aabb } vec3 taa_evalConstrainColor(vec3 sourceColor, vec2 sourceUV, vec2 sourceVel, vec3 candidateColor) { @@ -416,25 +416,25 @@ vec3 taa_evalConstrainColor(vec3 sourceColor, vec2 sourceUV, vec2 sourceVel, vec colorMinMaxAvg = taa_evalNeighbourColorVariance(sourceColor, sourceUV, sourceVel); - // clamp history to neighbourhood of current sample + // clamp history to neighbourhood of current sample return taa_clampColor(colorMinMaxAvg[0], colorMinMaxAvg[1], sourceColor, candidateColor); } vec3 taa_evalFeedbackColor(vec3 sourceColor, vec3 historyColor, float blendFactor) { const float _FeedbackMin = 0.1; const float _FeedbackMax = 0.9; - // feedback weight from unbiased luminance diff (t.lottes) - #if USE_YCOCG - float lum0 = sourceColor.r; - float lum1 = historyColor.r; - #else - float lum0 = Luminance(sourceColor.rgb); - float lum1 = Luminance(historyColor.rgb); - #endif - float unbiased_diff = abs(lum0 - lum1) / max(lum0, max(lum1, 0.2)); - float unbiased_weight = 1.0 - unbiased_diff; - float unbiased_weight_sqr = unbiased_weight * unbiased_weight; - float k_feedback = mix(_FeedbackMin, _FeedbackMax, unbiased_weight_sqr); + // feedback weight from unbiased luminance diff (t.lottes) + #if USE_YCOCG + float lum0 = sourceColor.r; + float lum1 = historyColor.r; + #else + float lum0 = Luminance(sourceColor.rgb); + float lum1 = Luminance(historyColor.rgb); + #endif + float unbiased_diff = abs(lum0 - lum1) / max(lum0, max(lum1, 0.2)); + float unbiased_weight = 1.0 - unbiased_diff; + float unbiased_weight_sqr = unbiased_weight * unbiased_weight; + float k_feedback = mix(_FeedbackMin, _FeedbackMax, unbiased_weight_sqr); vec3 nextColor = mix(historyColor, sourceColor, k_feedback * blendFactor).xyz; @@ -478,7 +478,7 @@ vec3 taa_evalFXAA(vec2 fragUV) { vec3 rgbSW = texture(sourceMap, fragUV + (vec2(-1.0, +1.0) * texelSize)).xyz; vec3 rgbSE = texture(sourceMap, fragUV + (vec2(+1.0, +1.0) * texelSize)).xyz; vec3 rgbM = texture(sourceMap, fragUV).xyz; - + // convert RGB values to luminance vec3 luma = vec3(0.299, 0.587, 0.114); float lumaNW = dot(rgbNW, luma); @@ -486,11 +486,11 @@ vec3 taa_evalFXAA(vec2 fragUV) { float lumaSW = dot(rgbSW, luma); float lumaSE = dot(rgbSE, luma); float lumaM = dot( rgbM, luma); - + // luma range of local neighborhood float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE))); float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE))); - + // direction perpendicular to local luma gradient vec2 dir; dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); @@ -502,7 +502,7 @@ vec3 taa_evalFXAA(vec2 fragUV) { float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce); dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX), max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), dir * rcpDirMin)) * texelSize; - + // perform additional texture sampling perpendicular to gradient vec3 rgbA = (1.0 / 2.0) * ( texture(sourceMap, fragUV + dir * (1.0 / 3.0 - 0.5)).xyz + diff --git a/libraries/render-utils/src/taa_blend.slf b/libraries/render-utils/src/taa_blend.slf index d2e23b590f..1027ddf074 100644 --- a/libraries/render-utils/src/taa_blend.slf +++ b/libraries/render-utils/src/taa_blend.slf @@ -23,7 +23,7 @@ void main(void) { // Pixel being shaded - vec3 sourceColor = texture(sourceMap, varTexCoord0).xyz; + vec3 sourceColor = texture(sourceMap, varTexCoord0).xyz; vec2 imageSize = getWidthHeight(0); vec2 texelSize = getInvWidthHeight(); @@ -124,9 +124,9 @@ void main(void) { // draw region splitter if ((abs(distToRegionDebug) < getInvWidthHeight().x) || (abs(distToRegionFXAA) < getInvWidthHeight().x)) { - outFragColor.rgb = vec3(1.0, 1.0, 0.0); - return; - } + outFragColor.rgb = vec3(1.0, 1.0, 0.0); + return; + } if (distToRegionFXAA > 0.0) { return; @@ -138,7 +138,7 @@ void main(void) { return; } - outFragColor = vec4(nextColor, 1.0); + outFragColor = vec4(nextColor, 1.0); vec3 prevColor = nextColor; diff --git a/libraries/render-utils/src/velocityBuffer_cameraMotion.slf b/libraries/render-utils/src/velocityBuffer_cameraMotion.slf index 6932766d63..083440dbf8 100644 --- a/libraries/render-utils/src/velocityBuffer_cameraMotion.slf +++ b/libraries/render-utils/src/velocityBuffer_cameraMotion.slf @@ -27,11 +27,11 @@ void main(void) { ivec4 stereoSide; ivec2 framePixelPos = getPixelPosTexcoordPosAndSide(gl_FragCoord.xy, pixelPos, texcoordPos, stereoSide); - float Zdb = texelFetch(depthMap, ivec2(gl_FragCoord.xy), 0).x; + float Zdb = texelFetch(depthMap, ivec2(gl_FragCoord.xy), 0).x; - // The position of the pixel fragment in Eye space then in world space + // The position of the pixel fragment in Eye space then in world space vec3 eyePos = evalUnjitteredEyePositionFromZdb(stereoSide.x, Zdb, texcoordPos); - vec3 worldPos = (getViewInverse() * vec4(eyePos, 1.0)).xyz; + vec3 worldPos = (getViewInverse() * vec4(eyePos, 1.0)).xyz; vec3 prevEyePos = (getPreviousView() * vec4(worldPos, 1.0)).xyz; vec4 prevClipPos = (getUnjitteredProjection(stereoSide.x) * vec4(prevEyePos, 1.0)); diff --git a/libraries/render-utils/src/zone_drawKeyLight.slf b/libraries/render-utils/src/zone_drawKeyLight.slf index 99e9357cb0..7174914ed8 100644 --- a/libraries/render-utils/src/zone_drawKeyLight.slf +++ b/libraries/render-utils/src/zone_drawKeyLight.slf @@ -36,7 +36,7 @@ void main(void) { vec3 outSpherePos = normalize(vec3(sphereUV, -sqrt(1.0 - sphereR2))); vec3 outNormal = vec3(getViewInverse() * vec4(outSpherePos, 0.0)); - float val = step(SUN_THRESHOLD, dot(-lightDirection, outNormal)); + float val = step(SUN_THRESHOLD, dot(-lightDirection, outNormal)); color = lightIrradiance * vec3(val); @@ -45,7 +45,7 @@ void main(void) { vec3 inSpherePos = normalize(vec3(inSphereUV, sqrt(1.0 - dot(inSphereUV.xy, inSphereUV.xy)))); vec3 inNormal = vec3(getViewInverse() * vec4(inSpherePos, 0.0)); - vec3 marbleColor = max(lightIrradiance * vec3(dot(-lightDirection, inNormal)), vec3(0.01)); + vec3 marbleColor = max(lightIrradiance * vec3(dot(-lightDirection, inNormal)), vec3(0.01)); color += marbleColor; } diff --git a/libraries/render/src/render/drawItemStatus.slf b/libraries/render/src/render/drawItemStatus.slf index 309a73ae15..9409ee6171 100644 --- a/libraries/render/src/render/drawItemStatus.slf +++ b/libraries/render/src/render/drawItemStatus.slf @@ -18,7 +18,7 @@ layout(location=0) out vec4 outFragColor; layout(binding=0) uniform sampler2D _icons; vec2 getIconTexcoord(float icon, vec2 uv) { const vec2 ICON_COORD_SIZE = vec2(0.0625, 1.0); - return vec2((uv.x + icon) * ICON_COORD_SIZE.x, uv.y * ICON_COORD_SIZE.y); + return vec2((uv.x + icon) * ICON_COORD_SIZE.x, uv.y * ICON_COORD_SIZE.y); } void main(void) { From 69ae04ab095f6619ed65d4c6ac2a1b73923c7766 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 6 Sep 2018 09:03:28 -0700 Subject: [PATCH 303/545] protect Base3DOverlay::_name with a mutex --- interface/src/ui/overlays/Base3DOverlay.cpp | 20 ++++++++++++++++++-- interface/src/ui/overlays/Base3DOverlay.h | 5 +++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index 6bce9d9283..767afca3e7 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -238,7 +238,9 @@ void Base3DOverlay::setProperties(const QVariantMap& originalProperties) { */ QVariant Base3DOverlay::getProperty(const QString& property) { if (property == "name") { - return _name; + return _nameLock.resultWithReadLock([&] { + return _name; + } } if (property == "position" || property == "start" || property == "p1" || property == "point") { return vec3toVariant(getWorldPosition()); @@ -346,6 +348,20 @@ void Base3DOverlay::setVisible(bool visible) { notifyRenderVariableChange(); } +QString Base3DOverlay::getName() const { + return _nameLock.resultWithReadLock([&] { + return QString("Overlay:") + _name; + } +} + +void Base3DOverlay::setName(QString name) { + _nameLock.withWriteLock([&] { + _name = name; + }); +} + + + render::ItemKey Base3DOverlay::getKey() { auto builder = render::ItemKey::Builder(Overlay::getKey()); @@ -364,4 +380,4 @@ render::ItemKey Base3DOverlay::getKey() { } return builder.build(); -} \ No newline at end of file +} diff --git a/interface/src/ui/overlays/Base3DOverlay.h b/interface/src/ui/overlays/Base3DOverlay.h index d44c193055..6f6092a42e 100644 --- a/interface/src/ui/overlays/Base3DOverlay.h +++ b/interface/src/ui/overlays/Base3DOverlay.h @@ -29,8 +29,8 @@ public: virtual OverlayID getOverlayID() const override { return OverlayID(getID().toString()); } void setOverlayID(OverlayID overlayID) override { setID(overlayID); } - virtual QString getName() const override { return QString("Overlay:") + _name; } - void setName(QString name) { _name = name; } + virtual QString getName() const override; + void setName(QString name); // getters virtual bool is3D() const override { return true; } @@ -107,6 +107,7 @@ protected: mutable bool _renderVariableDirty { true }; QString _name; + mutable ReadWriteLockable _nameLock; }; #endif // hifi_Base3DOverlay_h From 50f4932d9cee4d3d9d74c5c75c9267b37ece9d32 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 6 Sep 2018 09:07:53 -0700 Subject: [PATCH 304/545] PR feedback: structure alignement and size --- .../entities-renderer/src/RenderablePolyVoxEntityItem.cpp | 4 ++-- libraries/entities-renderer/src/polyvox.slf | 2 +- libraries/entities-renderer/src/polyvox_fade.slf | 2 +- libraries/render-utils/src/AntialiasingEffect.cpp | 6 +++--- libraries/render-utils/src/fxaa_blend.slf | 4 ++-- libraries/render-utils/src/sdf_text3D.slf | 4 ++-- libraries/render-utils/src/sdf_text3D_transparent.slf | 4 ++-- libraries/render-utils/src/text/Font.cpp | 4 ++-- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index 292b6368bb..a4a5a34683 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -1609,7 +1609,7 @@ PolyVoxEntityRenderer::PolyVoxEntityRenderer(const EntityItemPointer& entity) : _vertexFormat->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0); _vertexFormat->setAttribute(gpu::Stream::NORMAL, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 12); }); - _params = std::make_shared(sizeof(glm::vec3), nullptr); + _params = std::make_shared(sizeof(glm::vec4), nullptr); } ShapeKey PolyVoxEntityRenderer::getShapeKey() { @@ -1673,7 +1673,7 @@ void PolyVoxEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& s void PolyVoxEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { _lastVoxelToWorldMatrix = entity->voxelToWorldMatrix(); _lastVoxelVolumeSize = entity->getVoxelVolumeSize(); - _params->setSubData(0, _lastVoxelVolumeSize); + _params->setSubData(0, vec4(_lastVoxelVolumeSize, 0.0)); graphics::MeshPointer newMesh; entity->withReadLock([&] { newMesh = entity->_mesh; diff --git a/libraries/entities-renderer/src/polyvox.slf b/libraries/entities-renderer/src/polyvox.slf index e45bdc1a6b..441dfc11e5 100644 --- a/libraries/entities-renderer/src/polyvox.slf +++ b/libraries/entities-renderer/src/polyvox.slf @@ -25,7 +25,7 @@ layout(binding=ENTITIES_TEXTURE_POLYVOX_YMAP) uniform sampler2D yMap; layout(binding=ENTITIES_TEXTURE_POLYVOX_ZMAP) uniform sampler2D zMap; struct PolyvoxParams { - vec3 voxelVolumeSize; + vec4 voxelVolumeSize; }; layout(binding=0) uniform polyvoxParamsBuffer { diff --git a/libraries/entities-renderer/src/polyvox_fade.slf b/libraries/entities-renderer/src/polyvox_fade.slf index 0914debb3c..6e236193aa 100644 --- a/libraries/entities-renderer/src/polyvox_fade.slf +++ b/libraries/entities-renderer/src/polyvox_fade.slf @@ -28,7 +28,7 @@ layout(binding=ENTITIES_TEXTURE_POLYVOX_YMAP) uniform sampler2D yMap; layout(binding=ENTITIES_TEXTURE_POLYVOX_ZMAP) uniform sampler2D zMap; struct PolyvoxParams { - vec3 voxelVolumeSize; + vec4 voxelVolumeSize; }; layout(binding=0) uniform polyvoxParamsBuffer { diff --git a/libraries/render-utils/src/AntialiasingEffect.cpp b/libraries/render-utils/src/AntialiasingEffect.cpp index b3a645caed..17c13df19a 100644 --- a/libraries/render-utils/src/AntialiasingEffect.cpp +++ b/libraries/render-utils/src/AntialiasingEffect.cpp @@ -90,7 +90,7 @@ void Antialiasing::run(const render::RenderContextPointer& renderContext, const batch.setViewportTransform(args->_viewport); if (!_paramsBuffer) { - _paramsBuffer = std::make_shared(sizeof(glm::vec2), nullptr); + _paramsBuffer = std::make_shared(sizeof(glm::vec4), nullptr); } { @@ -109,7 +109,7 @@ void Antialiasing::run(const render::RenderContextPointer& renderContext, const _antialiasingBuffer->setRenderBuffer(0, _antialiasingTexture); glm::vec2 fbExtent { args->_viewport.z, args->_viewport.w }; glm::vec2 inverseFbExtent = 1.0f / fbExtent; - _paramsBuffer->setSubData(0, inverseFbExtent); + _paramsBuffer->setSubData(0, glm::vec4(inverseFbExtent, 0.0, 0.0)); } } @@ -280,7 +280,7 @@ void Antialiasing::run(const render::RenderContextPointer& renderContext, const batch.setResourceFramebufferSwapChainTexture(0, _antialiasingBuffers, 1); // Disable sharpen if FXAA if (!_blendParamsBuffer) { - _blendParamsBuffer = std::make_shared(sizeof(float), nullptr); + _blendParamsBuffer = std::make_shared(sizeof(glm::vec4), nullptr); } _blendParamsBuffer->setSubData(0, _sharpen * _params.get().regionInfo.z); batch.setUniformBuffer(0, _blendParamsBuffer); diff --git a/libraries/render-utils/src/fxaa_blend.slf b/libraries/render-utils/src/fxaa_blend.slf index 2b9db649ca..c051801659 100644 --- a/libraries/render-utils/src/fxaa_blend.slf +++ b/libraries/render-utils/src/fxaa_blend.slf @@ -20,7 +20,7 @@ layout(location=0) out vec4 outFragColor; layout(binding=0) uniform sampler2D colorTexture; struct FxaaBlendParams { - float sharpenIntensity; + vec4 sharpenIntensity; }; layout(binding=0) uniform fxaaBlendParamsBuffer { @@ -46,5 +46,5 @@ void main(void) { vec4 minColor = max(vec4(0), pixels[4]-vec4(0.5)); vec4 maxColor = pixels[4]+vec4(0.5); - outFragColor = clamp(pixels[4] + sharpenedPixel * params.sharpenIntensity, minColor, maxColor); + outFragColor = clamp(pixels[4] + sharpenedPixel * params.sharpenIntensity.x, minColor, maxColor); } diff --git a/libraries/render-utils/src/sdf_text3D.slf b/libraries/render-utils/src/sdf_text3D.slf index 0a177cb58f..d35396e469 100644 --- a/libraries/render-utils/src/sdf_text3D.slf +++ b/libraries/render-utils/src/sdf_text3D.slf @@ -17,7 +17,7 @@ layout(binding=0) uniform sampler2D Font; struct TextParams { vec4 color; - float outline; + vec4 outline; }; layout(binding=0) uniform textParamsBuffer { @@ -39,7 +39,7 @@ const float taaBias = pow(2.0, TAA_TEXTURE_LOD_BIAS); float evalSDF(vec2 texCoord) { // retrieve signed distance float sdf = textureLod(Font, texCoord, TAA_TEXTURE_LOD_BIAS).g; - if (params.outline > 0.0) { + if (params.outline.x > 0.0) { if (sdf > interiorCutoff) { sdf = 1.0 - sdf; } else { diff --git a/libraries/render-utils/src/sdf_text3D_transparent.slf b/libraries/render-utils/src/sdf_text3D_transparent.slf index d4c4fcc409..9dffca2038 100644 --- a/libraries/render-utils/src/sdf_text3D_transparent.slf +++ b/libraries/render-utils/src/sdf_text3D_transparent.slf @@ -17,7 +17,7 @@ layout(binding=0) uniform sampler2D Font; struct TextParams { vec4 color; - float outline; + vec4 outline; }; layout(binding=0) uniform textParamsBuffer { @@ -38,7 +38,7 @@ const float outlineExpansion = 0.2; void main() { // retrieve signed distance float sdf = texture(Font, _texCoord0).g; - if (params.outline > 0.0) { + if (params.outline.x > 0.0) { if (sdf > interiorCutoff) { sdf = 1.0 - sdf; } else { diff --git a/libraries/render-utils/src/text/Font.cpp b/libraries/render-utils/src/text/Font.cpp index 5ae50a8c73..68a1e59dc3 100644 --- a/libraries/render-utils/src/text/Font.cpp +++ b/libraries/render-utils/src/text/Font.cpp @@ -356,7 +356,7 @@ void Font::drawString(gpu::Batch& batch, Font::DrawInfo& drawInfo, const QString struct GpuDrawParams { glm::vec4 color; - float outline; + glm::vec4 outline; }; if (!drawInfo.paramsBuffer || drawInfo.params.color != color || drawInfo.params.effect != effectType) { @@ -364,7 +364,7 @@ void Font::drawString(gpu::Batch& batch, Font::DrawInfo& drawInfo, const QString drawInfo.params.effect = effectType; GpuDrawParams gpuDrawParams; gpuDrawParams.color = ColorUtils::sRGBToLinearVec4(drawInfo.params.color); - gpuDrawParams.outline = (drawInfo.params.effect == OUTLINE_EFFECT) ? 1 : 0; + gpuDrawParams.outline.x = (drawInfo.params.effect == OUTLINE_EFFECT) ? 1 : 0; drawInfo.paramsBuffer = std::make_shared(sizeof(GpuDrawParams), nullptr); drawInfo.paramsBuffer->setSubData(0, sizeof(GpuDrawParams), (const gpu::Byte*)&gpuDrawParams); } From 650f112f16bb0a2a7ae18b39be5eec65b8d31ec1 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 28 Aug 2018 17:00:27 -0700 Subject: [PATCH 305/545] Fix keyword in shader layout --- libraries/render-utils/src/simple_transparent_textured.slf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/render-utils/src/simple_transparent_textured.slf b/libraries/render-utils/src/simple_transparent_textured.slf index 0e6198de68..5573a7aa22 100644 --- a/libraries/render-utils/src/simple_transparent_textured.slf +++ b/libraries/render-utils/src/simple_transparent_textured.slf @@ -17,7 +17,7 @@ <@include render-utils/ShaderConstants.h@> // the albedo texture -layout(location=0) uniform sampler2D originalTexture; +layout(binding=0) uniform sampler2D originalTexture; // the interpolated normal layout(location=RENDER_UTILS_ATTR_NORMAL_WS) in vec3 _normalWS; From fade3a8de09b4c1f162c1cb03da3e676d8d47b2d Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Wed, 5 Sep 2018 12:39:12 -0700 Subject: [PATCH 306/545] Fixing shader implicit type conversions --- .../display-plugins/InterleavedSrgbToLinear.slf | 2 +- .../entities-renderer/src/paintStroke_fade.slf | 2 +- libraries/gpu/src/gpu/Paint.slh | 2 +- libraries/render-utils/src/BloomThreshold.slf | 4 ++-- libraries/render-utils/src/Highlight.slh | 6 +++--- libraries/render-utils/src/Shadow.slh | 10 +++++----- libraries/render-utils/src/drawWorkloadView.slv | 2 +- libraries/render-utils/src/fxaa.slf | 2 +- .../src/lightClusters_drawClusterContent.slf | 4 ++-- .../src/lightClusters_drawClusterContent.slv | 2 +- .../src/lightClusters_drawClusterFromDepth.slf | 2 +- libraries/render-utils/src/simple_fade.slf | 4 ++-- libraries/render-utils/src/ssao.slh | 16 ++++++++-------- .../render-utils/src/ssao_debugOcclusion.slf | 6 +++--- .../render-utils/src/ssao_makeOcclusion.slf | 9 +++++---- .../src/subsurfaceScattering_drawScattering.slf | 2 +- libraries/render-utils/src/taa.slh | 4 ++-- libraries/render-utils/src/taa_blend.slf | 6 +++--- libraries/render-utils/src/zone_drawAmbient.slf | 2 +- libraries/render/src/render/drawCellBounds.slv | 2 +- 20 files changed, 45 insertions(+), 44 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/InterleavedSrgbToLinear.slf b/libraries/display-plugins/src/display-plugins/InterleavedSrgbToLinear.slf index 5f7b3f3411..17dedce7f9 100644 --- a/libraries/display-plugins/src/display-plugins/InterleavedSrgbToLinear.slf +++ b/libraries/display-plugins/src/display-plugins/InterleavedSrgbToLinear.slf @@ -11,7 +11,7 @@ layout(location=0) in vec2 varTexCoord0; layout(location=0) out vec4 outFragColor; void main(void) { - ivec2 texCoord = ivec2(floor(varTexCoord0 * textureData.textureSize)); + ivec2 texCoord = ivec2(floor(varTexCoord0 * vec2(textureData.textureSize))); texCoord.x /= 2; int row = int(floor(gl_FragCoord.y)); if (row % 2 > 0) { diff --git a/libraries/entities-renderer/src/paintStroke_fade.slf b/libraries/entities-renderer/src/paintStroke_fade.slf index 8739c9bb9b..e5f70c8038 100644 --- a/libraries/entities-renderer/src/paintStroke_fade.slf +++ b/libraries/entities-renderer/src/paintStroke_fade.slf @@ -45,7 +45,7 @@ void main(void) { int frontCondition = 1 -int(gl_FrontFacing) * 2; vec3 color = varColor.rgb; packDeferredFragmentTranslucent( - interpolatedNormal * frontCondition, + interpolatedNormal * float(frontCondition), texel.a * varColor.a, polyline.color * texel.rgb + fadeEmissive, vec3(0.01, 0.01, 0.01), diff --git a/libraries/gpu/src/gpu/Paint.slh b/libraries/gpu/src/gpu/Paint.slh index 5f49b20b30..54a1214e12 100644 --- a/libraries/gpu/src/gpu/Paint.slh +++ b/libraries/gpu/src/gpu/Paint.slh @@ -17,7 +17,7 @@ float paintStripe(float value, float offset, float scale, float edge) { float width = fwidth(value); float normalizedWidth = width * scale; - float x0 = (value + offset) * scale - normalizedWidth / 2; + float x0 = (value + offset) * scale - normalizedWidth / 2.0; float x1 = x0 + normalizedWidth; float balance = 1.0 - edge; diff --git a/libraries/render-utils/src/BloomThreshold.slf b/libraries/render-utils/src/BloomThreshold.slf index 621aa31622..47a1fb0d9f 100644 --- a/libraries/render-utils/src/BloomThreshold.slf +++ b/libraries/render-utils/src/BloomThreshold.slf @@ -30,7 +30,7 @@ void main(void) { for (int x=0 ; x } else { - vec2 halfTexel = getInvWidthHeight() / 2; + vec2 halfTexel = getInvWidthHeight() / 2.0; vec2 texCoord0 = varTexCoord0+halfTexel; float weight = 0.0; - vec2 deltaUv = params._size / params._blurKernelSize; + vec2 deltaUv = params._size / float(params._blurKernelSize); vec2 lineStartUv = texCoord0 - params._size / 2.0; vec2 uv; int x; @@ -87,7 +87,7 @@ void main(void) { } } - if (intensity > 0) { + if (intensity > 0.0) { // sumOutlineDepth /= intensity; } else { sumOutlineDepth = FAR_Z; diff --git a/libraries/render-utils/src/Shadow.slh b/libraries/render-utils/src/Shadow.slh index db1c3b4d85..5115a876fe 100644 --- a/libraries/render-utils/src/Shadow.slh +++ b/libraries/render-utils/src/Shadow.slh @@ -67,10 +67,10 @@ ShadowSampleOffsets evalShadowFilterOffsets(vec4 position) { ivec2 offset = coords & ivec2(1,1); offset.y = (offset.x+offset.y) & 1; - offsets.points[0] = shadowScale * vec3(offset + PCFkernel[0], 0.0); - offsets.points[1] = shadowScale * vec3(offset + PCFkernel[1], 0.0); - offsets.points[2] = shadowScale * vec3(offset + PCFkernel[2], 0.0); - offsets.points[3] = shadowScale * vec3(offset + PCFkernel[3], 0.0); + offsets.points[0] = shadowScale * vec3(vec2(offset) + PCFkernel[0], 0.0); + offsets.points[1] = shadowScale * vec3(vec2(offset) + PCFkernel[1], 0.0); + offsets.points[2] = shadowScale * vec3(vec2(offset) + PCFkernel[2], 0.0); + offsets.points[3] = shadowScale * vec3(vec2(offset) + PCFkernel[3], 0.0); return offsets; } @@ -104,7 +104,7 @@ float evalShadowAttenuation(vec3 worldLightDir, vec4 worldPosition, float viewDe vec3 cascadeMix; bvec4 isPixelOnCascade; int cascadeIndex; - float oneMinusNdotL = 1.0 - clamp(dot(worldLightDir, worldNormal), 0, 1); + float oneMinusNdotL = 1.0 - clamp(dot(worldLightDir, worldNormal), 0.0, 1.0); for (cascadeIndex=0 ; cascadeIndex lateralDir = normalize(cross(vec3(0.0, 0.0, 1.0), normalize(tanEye))); - posEye.xyz += (0.005 * abs(posEye.z) * (regionID + 1)) * (-1.0 + 2.0 * float(segmentVertexID)) * lateralDir; + posEye.xyz += (0.005 * abs(posEye.z) * float(regionID + 1)) * (-1.0 + 2.0 * float(segmentVertexID)) * lateralDir; varEyePos = posEye.xyz; <$transformEyeToClipPos(cam, posEye, gl_Position)$> diff --git a/libraries/render-utils/src/fxaa.slf b/libraries/render-utils/src/fxaa.slf index 2c5e1cdc31..f1096a3054 100644 --- a/libraries/render-utils/src/fxaa.slf +++ b/libraries/render-utils/src/fxaa.slf @@ -68,7 +68,7 @@ void main() { outFragColor.w = 1.0; }*/ - if (gl_FragCoord.x > 800) { + if (gl_FragCoord.x > 800.0) { /* // filter width limit for dependent "two-tap" texture samples float FXAA_SPAN_MAX = 8.0; diff --git a/libraries/render-utils/src/lightClusters_drawClusterContent.slf b/libraries/render-utils/src/lightClusters_drawClusterContent.slf index 65ae8f423e..27cb838566 100644 --- a/libraries/render-utils/src/lightClusters_drawClusterContent.slf +++ b/libraries/render-utils/src/lightClusters_drawClusterContent.slf @@ -42,7 +42,7 @@ void main(void) { ivec3 cluster = clusterGrid_getCluster(clusterIndex); int numLights = cluster.x + cluster.y; - float numLightsScale = clamp(numLights * 0.05, 0.01, 1.0); + float numLightsScale = clamp(float(numLights) * 0.05, 0.01, 1.0); int clusterOffset = cluster.z; @@ -90,6 +90,6 @@ void main(void) { numLightTouching++; } - _fragColor = vec4(colorRamp(1.0 - (numLightTouching / 12.0f)), (numLightTouching > 0 ? 0.5 + 0.5 * numLightsScale : 0.0)); + _fragColor = vec4(colorRamp(1.0 - (float(numLightTouching) / 12.0f)), (numLightTouching > 0 ? 0.5 + 0.5 * numLightsScale : 0.0)); } diff --git a/libraries/render-utils/src/lightClusters_drawClusterContent.slv b/libraries/render-utils/src/lightClusters_drawClusterContent.slv index d7e4a66a6a..1303cf3926 100644 --- a/libraries/render-utils/src/lightClusters_drawClusterContent.slv +++ b/libraries/render-utils/src/lightClusters_drawClusterContent.slv @@ -56,7 +56,7 @@ void main(void) { ivec3 cluster = clusterGrid_getCluster(gpu_InstanceID()); int numLights = cluster.x + cluster.y; - float numLightsScale = clamp(numLights * 0.1, 0.0, 1.0); + float numLightsScale = clamp(float(numLights) * 0.1, 0.0, 1.0); ivec3 clusterPos = frustumGrid_indexToCluster(gpu_InstanceID()); diff --git a/libraries/render-utils/src/lightClusters_drawClusterFromDepth.slf b/libraries/render-utils/src/lightClusters_drawClusterFromDepth.slf index 4efb60a259..abbd86dd70 100644 --- a/libraries/render-utils/src/lightClusters_drawClusterFromDepth.slf +++ b/libraries/render-utils/src/lightClusters_drawClusterFromDepth.slf @@ -39,7 +39,7 @@ void main(void) { ivec3 cluster = clusterGrid_getCluster(frustumGrid_clusterToIndex(clusterPos)); int numLights = cluster.x + cluster.y; - float numLightsScale = clamp(numLights * 0.05, 0.01, 1.0); + float numLightsScale = clamp(float(numLights) * 0.05, 0.01, 1.0); ivec3 dims = frustumGrid.dims.xyz; diff --git a/libraries/render-utils/src/simple_fade.slf b/libraries/render-utils/src/simple_fade.slf index e9f94c29bc..97ed0c570c 100644 --- a/libraries/render-utils/src/simple_fade.slf +++ b/libraries/render-utils/src/simple_fade.slf @@ -91,7 +91,7 @@ void main(void) { normal, 1.0, diffuse+fadeEmissive, - max(0, 1.0 - shininess / 128.0), + max(0.0, 1.0 - shininess / 128.0), DEFAULT_METALLIC, specular, specular); @@ -100,7 +100,7 @@ void main(void) { normal, 1.0, diffuse, - max(0, 1.0 - shininess / 128.0), + max(0.0, 1.0 - shininess / 128.0), length(specular), DEFAULT_EMISSIVE+fadeEmissive, DEFAULT_OCCLUSION, diff --git a/libraries/render-utils/src/ssao.slh b/libraries/render-utils/src/ssao.slh index 5341a1682a..b149d8f912 100644 --- a/libraries/render-utils/src/ssao.slh +++ b/libraries/render-utils/src/ssao.slh @@ -137,14 +137,14 @@ float getBlurCoef(int c) { float getAngleDitheringWorldPos(in vec3 pixelWorldPos) { vec3 worldPosFract = fract(pixelWorldPos * 1.0); - ivec3 pixelPos = ivec3(worldPosFract * 256); + ivec3 pixelPos = ivec3(worldPosFract * 256.0); - return isDitheringEnabled() * ((3 * pixelPos.x ^ pixelPos.y + pixelPos.x * pixelPos.y) + (3 * pixelPos.y ^ pixelPos.z + pixelPos.x * pixelPos.z)) * 10 + getFrameDithering(); + return isDitheringEnabled() * float(((3 * pixelPos.x ^ pixelPos.y + pixelPos.x * pixelPos.y) + (3 * pixelPos.y ^ pixelPos.z + pixelPos.x * pixelPos.z)) * 10) + getFrameDithering(); } float getAngleDithering(in ivec2 pixelPos) { // Hash function used in the AlchemyAO paper - return isDitheringEnabled() * (3 * pixelPos.x ^ pixelPos.y + pixelPos.x * pixelPos.y) * 10 + getFrameDithering(); + return isDitheringEnabled() * float((3 * pixelPos.x ^ pixelPos.y + pixelPos.x * pixelPos.y) * 10) + getFrameDithering(); } float evalDiskRadius(float Zeye, vec2 imageSize) { @@ -162,7 +162,7 @@ const float TWO_PI = 6.28; vec3 getUnitTapLocation(int sampleNumber, float spinAngle){ // Radius relative to ssR - float alpha = float(sampleNumber + 0.5) * getInvNumSamples(); + float alpha = (float(sampleNumber) + 0.5) * getInvNumSamples(); float angle = alpha * (getNumSpiralTurns() * TWO_PI) + spinAngle; return vec3(cos(angle), sin(angle), alpha); } @@ -219,7 +219,7 @@ vec3 getTapLocationClamped(int sampleNumber, float spinAngle, float outerRadius, if (redoTap) { tap.xy = tapPos - pixelPos; tap.z = length(tap.xy); - tap.z = 0; + tap.z = 0.0; } return tap; @@ -253,7 +253,7 @@ vec3 fetchTapUnfiltered(ivec4 side, ivec2 ssC, vec3 tap, vec2 imageSize) { vec2 tapUV = (vec2(ssP) + vec2(0.5)) / imageSize; - vec2 fetchUV = vec2(tapUV.x + side.w * 0.5 * (side.x - tapUV.x), tapUV.y); + vec2 fetchUV = vec2(tapUV.x + float(side.w) * 0.5 * (float(side.x) - tapUV.x), tapUV.y); vec3 P; P.xy = tapUV; @@ -263,7 +263,7 @@ vec3 fetchTapUnfiltered(ivec4 side, ivec2 ssC, vec3 tap, vec2 imageSize) { } vec3 fetchTap(ivec4 side, ivec2 ssC, vec3 tap, vec2 imageSize) { - int mipLevel = evalMipFromRadius(tap.z * doFetchMips()); + int mipLevel = evalMipFromRadius(tap.z * float(doFetchMips())); ivec2 ssP = ivec2(tap.xy) + ssC; ivec2 ssPFull = ivec2(ssP.x + side.y, ssP.y); @@ -276,7 +276,7 @@ vec3 fetchTap(ivec4 side, ivec2 ssC, vec3 tap, vec2 imageSize) { ivec2 mipP = clamp(ssPFull >> mipLevel, ivec2(0), mipSize - ivec2(1)); vec2 tapUV = (vec2(ssP) + vec2(0.5)) / imageSize; - vec2 fetchUV = vec2(tapUV.x + side.w * 0.5 * (side.x - tapUV.x), tapUV.y); + vec2 fetchUV = vec2(tapUV.x + float(side.w) * 0.5 * (float(side.x) - tapUV.x), tapUV.y); // vec2 tapUV = (vec2(mipP) + vec2(0.5)) / vec2(mipSize); vec3 P; diff --git a/libraries/render-utils/src/ssao_debugOcclusion.slf b/libraries/render-utils/src/ssao_debugOcclusion.slf index 007fd0cd7b..ab7989e35e 100644 --- a/libraries/render-utils/src/ssao_debugOcclusion.slf +++ b/libraries/render-utils/src/ssao_debugOcclusion.slf @@ -84,15 +84,15 @@ void main(void) { float keepTapRadius = 1.0; int keepedMip = -1; bool keep = false; - - for (int i = 0; i < getNumSamples(); ++i) { + int sampleCount = int(getNumSamples()); + for (int i = 0; i < sampleCount; ++i) { vec3 tap = getTapLocationClamped(i, randomPatternRotationAngle, ssDiskRadius, cursorPixelPos, imageSize); // The occluding point in camera space vec2 fragToTap = vec2(ssC) + tap.xy - fragCoord.xy; if (dot(fragToTap,fragToTap) < keepTapRadius) { keep = true; - keepedMip = evalMipFromRadius(tap.z * doFetchMips()); + keepedMip = evalMipFromRadius(tap.z * float(doFetchMips())); } vec3 tapUVZ = fetchTap(side, ssC, tap, imageSize); diff --git a/libraries/render-utils/src/ssao_makeOcclusion.slf b/libraries/render-utils/src/ssao_makeOcclusion.slf index 1b638d4270..3934b9eddc 100644 --- a/libraries/render-utils/src/ssao_makeOcclusion.slf +++ b/libraries/render-utils/src/ssao_makeOcclusion.slf @@ -52,8 +52,9 @@ void main(void) { // Accumulate the Obscurance for each samples float sum = 0.0; - for (int i = 0; i < getNumSamples(); ++i) { - vec3 tap = getTapLocationClamped(i, randomPatternRotationAngle, ssDiskRadius, ssC, imageSize); + int sampleCount = int(getNumSamples()); + for (int i = 0; i < sampleCount; ++i) { + vec3 tap = getTapLocationClamped(i, randomPatternRotationAngle, ssDiskRadius, vec2(ssC), imageSize); vec3 tapUVZ = fetchTap(side, ssC, tap, imageSize); @@ -68,10 +69,10 @@ void main(void) { // Bilateral box-filter over a quad for free, respecting depth edges // (the difference that this makes is subtle) if (abs(dFdx(Cp.z)) < 0.02) { - A -= dFdx(A) * ((ssC.x & 1) - 0.5); + A -= dFdx(A) * (float(ssC.x & 1) - 0.5); } if (abs(dFdy(Cp.z)) < 0.02) { - A -= dFdy(A) * ((ssC.y & 1) - 0.5); + A -= dFdy(A) * (float(ssC.y & 1) - 0.5); } diff --git a/libraries/render-utils/src/subsurfaceScattering_drawScattering.slf b/libraries/render-utils/src/subsurfaceScattering_drawScattering.slf index 9410a2ed2b..8664fa16fd 100644 --- a/libraries/render-utils/src/subsurfaceScattering_drawScattering.slf +++ b/libraries/render-utils/src/subsurfaceScattering_drawScattering.slf @@ -80,7 +80,7 @@ vec3 drawScatteringTableUV(vec2 cursor, vec2 texcoord) { vec3 distance = vec3(0.0); for (int c = 0; c < 3; c++) { - vec2 BRDFuv = vec2(clamp(bentNdotL[c] * 0.5 + 0.5, 0.0, 1.0), clamp(2 * curvature, 0.0, 1.0)); + vec2 BRDFuv = vec2(clamp(bentNdotL[c] * 0.5 + 0.5, 0.0, 1.0), clamp(2.0 * curvature, 0.0, 1.0)); vec2 delta = BRDFuv - texcoord; distance[c] = 1.0 - dot(delta, delta); } diff --git a/libraries/render-utils/src/taa.slh b/libraries/render-utils/src/taa.slh index 1692c33ef6..2161ad9524 100644 --- a/libraries/render-utils/src/taa.slh +++ b/libraries/render-utils/src/taa.slh @@ -117,7 +117,7 @@ vec2 taa_fetchVelocityMap(vec2 uv) { } float taa_fetchDepth(vec2 uv) { - return -texture(depthMap, vec2(uv), 0).x; + return -texture(depthMap, vec2(uv), 0.0).x; } @@ -230,7 +230,7 @@ vec2 taa_fromEyeUVToFragUV(vec2 eyeUV, int stereoSide) { vec2 fragUV = eyeUV; if (isStereo()) { fragUV.x *= 0.5; - fragUV.x += stereoSide*0.5; + fragUV.x += float(stereoSide)*0.5; } return fragUV; } diff --git a/libraries/render-utils/src/taa_blend.slf b/libraries/render-utils/src/taa_blend.slf index 1027ddf074..50575a6a07 100644 --- a/libraries/render-utils/src/taa_blend.slf +++ b/libraries/render-utils/src/taa_blend.slf @@ -57,7 +57,7 @@ void main(void) { vec2 cursorVelocityDir = cursorVelocity / cursorVelocityLength; vec2 cursorVelocityNor = vec2(cursorVelocityDir.y, -cursorVelocityDir.x); - if ((dot(cursorVelocityDir, cursorToFragVec) < 0) && abs(dot(cursorVelocityNor, cursorToFragVec)) < 1.0) { + if ((dot(cursorVelocityDir, cursorToFragVec) < 0.0) && abs(dot(cursorVelocityNor, cursorToFragVec)) < 1.0) { vec3 speedColor = taa_getVelocityColorRelative(cursorToFragLength); @@ -69,7 +69,7 @@ void main(void) { float tenPercentHeight = 0.1 * imageSize.y; float centerWidth = imageSize.x * 0.5; - //vec2 nextOrbPos = vec2(centerWidth, imageSize.y - 3 * tenPercentHeight); + //vec2 nextOrbPos = vec2(centerWidth, imageSize.y - 3.0 * tenPercentHeight); vec2 nextOrbPos = cursorPos; vec2 nextOrbPosToPix = pixPos - nextOrbPos; float nextOrbPosToPixLength = length(nextOrbPosToPix); @@ -146,7 +146,7 @@ void main(void) { prevColor = texture(historyMap, prevTexCoord).xyz; } - outFragColor.xyz = mix(prevColor, vec3(1,0,1), clamp(distance(prevColor, nextColor) - 0.01, 0, 1)); + outFragColor.xyz = mix(prevColor, vec3(1,0,1), clamp(distance(prevColor, nextColor) - 0.01, 0.0, 1.0)); if (pixVelocityLength > params.debugShowVelocityThreshold) { vec3 speedColor = taa_getVelocityColorAboveThreshold(pixVelocityLength); diff --git a/libraries/render-utils/src/zone_drawAmbient.slf b/libraries/render-utils/src/zone_drawAmbient.slf index e560d91308..f20d83e913 100644 --- a/libraries/render-utils/src/zone_drawAmbient.slf +++ b/libraries/render-utils/src/zone_drawAmbient.slf @@ -44,7 +44,7 @@ void main(void) { // vec3 ambient = sphericalHarmonics_evalSphericalLight(getLightAmbientSphere(lightAmbient), fragNormal).xyz; // _fragColor = vec4( 0.5 * (fragNormal + vec3(1.0)), 1.0); - vec3 color = (sphereUV.x > 0 ? ambientMap : ambientSH); + vec3 color = (sphereUV.x > 0.0 ? ambientMap : ambientSH); color = color * 1.0 - base.w + base.xyz * base.w; const float INV_GAMMA_22 = 1.0 / 2.2; diff --git a/libraries/render/src/render/drawCellBounds.slv b/libraries/render/src/render/drawCellBounds.slv index 913a3a372a..24cc6254fd 100644 --- a/libraries/render/src/render/drawCellBounds.slv +++ b/libraries/render/src/render/drawCellBounds.slv @@ -61,5 +61,5 @@ void main(void) { TransformObject obj = getTransformObject(); <$transformModelToClipPos(cam, obj, pos, gl_Position)$> - varColor = vec4(colorWheel(fract(float(inCellLocation.w) / 5.0)), 0.8 + 0.2 * cellIsEmpty); + varColor = vec4(colorWheel(fract(float(inCellLocation.w) / 5.0)), 0.8 + 0.2 * float(cellIsEmpty)); } \ No newline at end of file From 5a0a259c214b4a3a4fc7dc2467f3b7d3a1935159 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 6 Sep 2018 09:37:01 -0700 Subject: [PATCH 307/545] dammit --- interface/src/ui/overlays/Base3DOverlay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index 767afca3e7..89e6fac3dc 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -240,7 +240,7 @@ QVariant Base3DOverlay::getProperty(const QString& property) { if (property == "name") { return _nameLock.resultWithReadLock([&] { return _name; - } + }); } if (property == "position" || property == "start" || property == "p1" || property == "point") { return vec3toVariant(getWorldPosition()); From 042044ceaf061aa9c4b6d7f1eed4965718f36ae3 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 6 Sep 2018 09:38:12 -0700 Subject: [PATCH 308/545] dammit --- interface/src/ui/overlays/Base3DOverlay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index 89e6fac3dc..1d8db69e26 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -351,7 +351,7 @@ void Base3DOverlay::setVisible(bool visible) { QString Base3DOverlay::getName() const { return _nameLock.resultWithReadLock([&] { return QString("Overlay:") + _name; - } + }); } void Base3DOverlay::setName(QString name) { From 01424b81792f3e2e1a38db327f2be59f899f2851 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Thu, 6 Sep 2018 09:39:33 -0700 Subject: [PATCH 309/545] Head Collision Pick added --- .../controllers/controllerModules/teleport.js | 108 +++++++++++------- 1 file changed, 69 insertions(+), 39 deletions(-) diff --git a/scripts/system/controllers/controllerModules/teleport.js b/scripts/system/controllers/controllerModules/teleport.js index 2dea25fc78..92fc91094d 100644 --- a/scripts/system/controllers/controllerModules/teleport.js +++ b/scripts/system/controllers/controllerModules/teleport.js @@ -173,38 +173,6 @@ Script.include("/~/system/libraries/controllers.js"); renderStates: teleportRenderStates, maxDistance: 8.0 }); - - this.teleportCollisionPick; - - this.recreateCollisionPick = function() { - if (_this.teleportCollisionPick !== undefined) { - Picks.removePick(_this.teleportCollisionPick); - } - - var capsuleData = MyAvatar.getCollisionCapsule(); - var capsuleHeight = Vec3.distance(capsuleData.start, capsuleData.end); - var offset = Vec3.distance(Vec3.sum(capsuleData.start, {x: 0, y: 0.5*capsuleHeight, z: 0}), MyAvatar.position); - var radius = capsuleData.radius; - var height = 2.0 * radius + capsuleHeight; - - _this.teleportCollisionPick = Picks.createPick(PickType.Collision, { - enabled: true, - parentID: Pointers.getPointerProperties(_this.teleportParabolaHandInvisible).renderStates["invisible"].end, - filter: Picks.PICK_ENTITIES + Picks.PICK_AVATARS, - shape: { - shapeType: "capsule-y", - dimensions: { - x: radius * 2.0, - y: height - (radius * 2.0), - z: radius * 2.0 - } - }, - position: { x: 0, y: offset + (height * 0.5), z: 0 }, - threshold: _this.capsuleThreshold - }); - } - - _this.recreateCollisionPick(); this.teleportParabolaHeadVisible = Pointers.createPointer(PickType.Parabola, { joint: "Avatar", @@ -232,13 +200,67 @@ Script.include("/~/system/libraries/controllers.js"); renderStates: teleportRenderStates, maxDistance: 8.0 }); + + this.teleportHeadCollisionPick; + this.teleportHandCollisionPick; + + this.recreateCollisionPicks = function() { + + if (_this.teleportHandCollisionPick !== undefined) { + Picks.removePick(_this.teleportHandCollisionPick); + } + if (_this.teleportHeadCollisionPick !== undefined) { + Picks.removePick(_this.teleportHeadCollisionPick); + } + var capsuleData = MyAvatar.getCollisionCapsule(); + var capsuleHeight = Vec3.distance(capsuleData.start, capsuleData.end); + var offset = Vec3.distance(Vec3.sum(capsuleData.start, {x: 0, y: 0.5*capsuleHeight, z: 0}), MyAvatar.position); + var radius = capsuleData.radius; + var height = 2.0 * radius + capsuleHeight; + var scale = height/2.0; + + _this.teleportHandCollisionPick = Picks.createPick(PickType.Collision, { + enabled: true, + parentID: Pointers.getPointerProperties(_this.teleportParabolaHandInvisible).renderStates["invisible"].end, + filter: Picks.PICK_ENTITIES + Picks.PICK_AVATARS, + shape: { + shapeType: "capsule-y", + dimensions: { + x: radius * 2.0, + y: height - (radius * 2.0), + z: radius * 2.0 + } + }, + position: { x: 0, y: offset + (height * 0.5), z: 0 }, + threshold: scale * _this.capsuleThreshold + }); + + _this.teleportHeadCollisionPick = Picks.createPick(PickType.Collision, { + enabled: true, + parentID: Pointers.getPointerProperties(_this.teleportParabolaHeadInvisible).renderStates["invisible"].end, + filter: Picks.PICK_ENTITIES + Picks.PICK_AVATARS, + shape: { + shapeType: "capsule-y", + dimensions: { + x: radius * 2.0, + y: height - (radius * 2.0), + z: radius * 2.0 + } + }, + position: { x: 0, y: offset + (height * 0.5), z: 0 }, + threshold: scale * _this.capsuleThreshold + }); + } + + _this.recreateCollisionPicks(); this.cleanup = function() { Pointers.removePointer(_this.teleportParabolaHandVisible); Pointers.removePointer(_this.teleportParabolaHandInvisible); Pointers.removePointer(_this.teleportParabolaHeadVisible); Pointers.removePointer(_this.teleportParabolaHeadInvisible); - Picks.removePick(_this.teleportCollisionPick); + Picks.removePick(_this.teleportHandCollisionPick); + Picks.removePick(_this.teleportHeadCollisionPick); }; this.axisButtonStateX = 0; // Left/right axis button pressed. @@ -307,13 +329,17 @@ Script.include("/~/system/libraries/controllers.js"); if (!pose.valid) { Pointers.disablePointer(_this.teleportParabolaHandVisible); Pointers.disablePointer(_this.teleportParabolaHandInvisible); + Picks.disablePick(_this.teleportHandCollisionPick); Pointers.enablePointer(_this.teleportParabolaHeadVisible); Pointers.enablePointer(_this.teleportParabolaHeadInvisible); + Picks.enablePick(_this.teleportHeadCollisionPick); } else { Pointers.enablePointer(_this.teleportParabolaHandVisible); Pointers.enablePointer(_this.teleportParabolaHandInvisible); + Picks.enablePick(_this.teleportHandCollisionPick); Pointers.disablePointer(_this.teleportParabolaHeadVisible); Pointers.disablePointer(_this.teleportParabolaHeadInvisible); + Picks.disablePick(_this.teleportHeadCollisionPick); } // We do up to 2 picks to find a teleport location. @@ -325,15 +351,17 @@ Script.include("/~/system/libraries/controllers.js"); // We might hit an invisible entity that is not a seat, so we need to do a second pass. // * In the second pass we pick against visible entities only. // - var result; + var result, collisionResult; if (mode === 'head') { result = Pointers.getPrevPickResult(_this.teleportParabolaHeadInvisible); + collisionResult = Picks.getPrevPickResult(_this.teleportHeadCollisionPick); } else { result = Pointers.getPrevPickResult(_this.teleportParabolaHandInvisible); + collisionResult = Picks.getPrevPickResult(_this.teleportHandCollisionPick); } - var collisionResult = Picks.getPrevPickResult(_this.teleportCollisionPick); var teleportLocationType = getTeleportTargetType(result, collisionResult); + if (teleportLocationType === TARGET.INVISIBLE) { if (mode === 'head') { result = Pointers.getPrevPickResult(_this.teleportParabolaHeadVisible); @@ -386,6 +414,8 @@ Script.include("/~/system/libraries/controllers.js"); Pointers.disablePointer(_this.teleportParabolaHandInvisible); Pointers.disablePointer(_this.teleportParabolaHeadVisible); Pointers.disablePointer(_this.teleportParabolaHeadInvisible); + Picks.disablePick(_this.teleportParabolaHeadInvisible); + Picks.disablePick(_this.teleportParabolaHandInvisible); }; this.setTeleportState = function(mode, visibleState, invisibleState) { @@ -610,13 +640,13 @@ Script.include("/~/system/libraries/controllers.js"); } var afterSet = new AfterSet(100, 30, function(value) { - leftTeleporter.recreateCollisionPick(); - rightTeleporter.recreateCollisionPick(); + leftTeleporter.recreateCollisionPicks(); + rightTeleporter.recreateCollisionPicks(); }); MyAvatar.onLoadComplete.connect(function () { - leftTeleporter.recreateCollisionPick(); - rightTeleporter.recreateCollisionPick(); + leftTeleporter.recreateCollisionPicks(); + rightTeleporter.recreateCollisionPicks(); }); MyAvatar.sensorToWorldScaleChanged.connect(function() { From 8a2096910395731344d1a2de7ecf5a07ff00012f Mon Sep 17 00:00:00 2001 From: Roxanne Skelly Date: Thu, 6 Sep 2018 10:38:10 -0700 Subject: [PATCH 310/545] Fix typo --- scripts/system/tablet-goto.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/tablet-goto.js b/scripts/system/tablet-goto.js index 80b4e67c43..8fafac7685 100644 --- a/scripts/system/tablet-goto.js +++ b/scripts/system/tablet-goto.js @@ -127,7 +127,7 @@ return; } stories[story.id] = story; - var message = story.username + " " + story.action_string + " " + story.place_name + ". Open GOTO to join them."; + var message = story.username + " " + story.action_string + " in " + story.place_name + ". Open GOTO to join them."; Window.displayAnnouncement(message); didNotify = true; }); From ec2d89fd25bd83128f413fca0b34207e74aabde6 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Thu, 6 Sep 2018 11:16:58 -0700 Subject: [PATCH 311/545] fixing toolbar disappering --- interface/src/Application.cpp | 2 -- scripts/system/interstitialPage.js | 7 ++++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1868d6db4b..73e2fce956 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3497,8 +3497,6 @@ void Application::setIsInterstitialMode(bool interstitialMode) { bool interstitialModeEnabled = menu->isOptionChecked("Enable Interstitial"); if (_interstitialMode != interstitialMode && interstitialModeEnabled) { _interstitialMode = interstitialMode; - - DependencyManager::get()->setPinned(_interstitialMode); emit interstitialModeChanged(_interstitialMode); } } diff --git a/scripts/system/interstitialPage.js b/scripts/system/interstitialPage.js index 86a9e744e9..c56e16d429 100644 --- a/scripts/system/interstitialPage.js +++ b/scripts/system/interstitialPage.js @@ -307,7 +307,6 @@ var THE_PLACE = "hifi://TheSpot-dev"; function clickedOnOverlay(overlayID, event) { - print(overlayID + " other: " + loadingToTheSpotID); if (loadingToTheSpotID === overlayID) { location.handleLookupString(THE_PLACE); } @@ -349,8 +348,10 @@ Overlays.editOverlay(loadingBarPlacard, properties); Overlays.editOverlay(loadingBarProgress, loadingBarProperties); - if (physicsEnabled && !HMD.active) { - toolbar.writeProperty("visible", true); + + Menu.setIsOptionChecked("Show Overlays", physicsEnabled); + if (!HMD.active) { + toolbar.writeProperty("visible", physicsEnabled); } resetValues(); From 385027321be1f58f7ee061adcdfa34438a22bff4 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Thu, 6 Sep 2018 11:18:35 -0700 Subject: [PATCH 312/545] fixing the eye open/closed pw image --- .../qml/LoginDialog/LinkAccountBody.qml | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index caf5ce0e53..cc682aa1ba 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -129,6 +129,7 @@ Item { } } ShortcutText { + id: forgotUsernameShortcut z: 10 anchors { leftMargin: usernameField.textFieldLabel.contentWidth + 10 @@ -149,24 +150,26 @@ Item { width: parent.width placeholderText: "Password" activeFocusOnPress: true + echoMode: TextInput.Password onFocusChanged: { root.text = ""; root.isPassword = true; } - Image { id: showPasswordImage - x: parent.width - 40 - height: parent.height - width: parent.width - (parent.width - 40) + x: parent.width - ((parent.height) * 31 / 23) + y: (parent.height - (parent.height * 16 / 23)) / 2 + width: parent.width - (parent.width - (((parent.height) * 31/23))) + height: parent.height * 16 / 23 source: "../../images/eyeOpen.svg" } Rectangle { + id: showPasswordHitbox z: 10 - x: parent.width - 40 - width: parent.width - (parent.width - 40) + x: parent.width - (parent.height * 31/16) + width: parent.width - (parent.width - (parent.height * 31/16)) height: parent.height color: "transparent" MouseArea { @@ -178,6 +181,13 @@ Item { showPassword = !showPassword; passwordField.echoMode = showPassword ? TextInput.Normal : TextInput.Password; showPasswordImage.source = showPassword ? "../../images/eyeClosed.svg" : "../../images/eyeOpen.svg"; + showPasswordImage.width = passwordField.width - (passwordField.width - (passwordField.height * 31/23)); + showPasswordImage.x = -(showPasswordImage.width - passwordField.width); + showPasswordImage.height = showPassword ? passwordField.height : passwordField.height * 16 / 23; + showPasswordImage.y = showPassword ? 0 : (passwordField.height - showPasswordImage.height) / 2; + showPasswordHitbox.width = showPasswordImage.width; + showPasswordHitbox.x = showPasswordImage.x; + } } } @@ -186,6 +196,7 @@ Item { } ShortcutText { + id: forgotPasswordShortcut z: 10 anchors { leftMargin: passwordField.textFieldLabel.contentWidth + 10 From 5aa45b64d2b7aede39a48d3997d017742c49d21d Mon Sep 17 00:00:00 2001 From: sam gateau Date: Thu, 6 Sep 2018 11:24:13 -0700 Subject: [PATCH 313/545] Adressing build warnings --- libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp | 2 +- libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp | 5 +++-- libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp index 21553dc2c7..9fe1aa4029 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp @@ -269,7 +269,7 @@ void GLBackend::updateInput() { auto stride = _input._bufferStrides.data(); // Profile the count of buffers to update and use it to short cut the for loop - int numInvalids = _input._invalidBuffers.count(); + int numInvalids = (int) _input._invalidBuffers.count(); _stats._ISNumInputBufferChanges += numInvalids; PROFILE_COUNTER_IF_CHANGED(render_gpu, "numInputBuffersbound", int, numInvalids); diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp index 30e393630a..cedb18c87a 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp @@ -78,10 +78,11 @@ void GL41Backend::updateInput() { const Stream::Format::AttributeMap& attributes = _input._format->getAttributes(); auto& inputChannels = _input._format->getChannels(); - _stats._ISNumInputBufferChanges += _input._invalidBuffers.count(); + int numInvalids = (int)_input._invalidBuffers.count(); + _stats._ISNumInputBufferChanges += numInvalids; // Profile the count of buffers to update - PROFILE_COUNTER_IF_CHANGED(render_gpu, "numInputBuffersbound", int, _input._invalidBuffers.count()); + PROFILE_COUNTER_IF_CHANGED(render_gpu, "numInputBuffersbound", int, numInvalids); GLuint boundVBO = 0; for (auto& channelIt : inputChannels) { diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp index de4989eb32..4a8bdc43f3 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp @@ -134,7 +134,7 @@ void GL45Backend::updateInput() { auto stride = _input._bufferStrides.data(); // Profile the count of buffers to update and use it to short cut the for loop - int numInvalids = _input._invalidBuffers.count(); + int numInvalids = (int) _input._invalidBuffers.count(); _stats._ISNumInputBufferChanges += numInvalids; PROFILE_COUNTER_IF_CHANGED(render_gpu, "numInputBuffersbound", int, numInvalids); From e428248472c13a67e7ea73785437379d68477327 Mon Sep 17 00:00:00 2001 From: sam gateau Date: Thu, 6 Sep 2018 11:33:26 -0700 Subject: [PATCH 314/545] Adressing build warnings --- libraries/graphics/src/graphics/Geometry.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/graphics/src/graphics/Geometry.cpp b/libraries/graphics/src/graphics/Geometry.cpp index f71dcbe27d..5a374ae8d0 100755 --- a/libraries/graphics/src/graphics/Geometry.cpp +++ b/libraries/graphics/src/graphics/Geometry.cpp @@ -116,7 +116,6 @@ Box Mesh::evalPartBound(int partNum) const { index += part._startIndex; auto endIndex = index; endIndex += part._numIndices; - auto vertices = &_vertexBuffer.get(part._baseVertex); for (;index != endIndex; index++) { // skip primitive restart indices if ((*index) != PRIMITIVE_RESTART_INDEX) { @@ -138,7 +137,6 @@ Box Mesh::evalPartsBound(int partStart, int partEnd) const { Box partBound; auto index = _indexBuffer.cbegin() + (*part)._startIndex; auto endIndex = index + (*part)._numIndices; - //auto vertices = &_vertexBuffer.get((*part)._baseVertex); for (;index != endIndex; index++) { // skip primitive restart indices if ((*index) != (uint) PRIMITIVE_RESTART_INDEX) { From a5038850f17af34940c3ed15fc38b335d74b8c1f Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Thu, 6 Sep 2018 11:37:35 -0700 Subject: [PATCH 315/545] right align forgot user/pw shortcuts --- interface/resources/qml/LoginDialog/LinkAccountBody.qml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index cc682aa1ba..902466270f 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -143,6 +143,9 @@ Item { linkColor: hifi.colors.blueAccent onLinkActivated: loginDialog.openUrl(link) + Component.onCompleted: { + forgotUsernameShortcut.x = root.implicitWidth - forgotUsernameShortcut.width; + } } TextField { @@ -210,6 +213,9 @@ Item { linkColor: hifi.colors.blueAccent onLinkActivated: loginDialog.openUrl(link) + Component.onCompleted: { + forgotPasswordShortcut.x = root.implicitWidth - forgotPasswordShortcut.width; + } } InfoItem { From e1aba52c239ea552201429bff57b4d396d969307 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Thu, 6 Sep 2018 12:09:44 -0700 Subject: [PATCH 316/545] Revert to statics for priority sort weights; update defaults from Andrew --- assignment-client/src/avatars/AvatarMixerSlave.cpp | 6 +++--- libraries/avatars/src/AvatarData.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index 9e38f465d3..a61f65ffb0 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -313,9 +313,9 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // prepare to sort const auto& cameraViews = nodeData->getViewFrustums(); PrioritySortUtil::PriorityQueue sortedAvatars(cameraViews, - /*AvatarData::_avatarSortCoefficientSize*/ 1.0f, // Suggested weights from Andrew M. - /*AvatarData::_avatarSortCoefficientCenter*/ 0.5f, - /*AvatarData::_avatarSortCoefficientAge*/ 0.25f); + AvatarData::_avatarSortCoefficientSize, + AvatarData::_avatarSortCoefficientCenter, + AvatarData::_avatarSortCoefficientAge); sortedAvatars.reserve(_end - _begin); for (auto listedNode = _begin; listedNode != _end; ++listedNode) { diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 3e822fd17a..6896883f74 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -2822,8 +2822,8 @@ void RayToAvatarIntersectionResultFromScriptValue(const QScriptValue& object, Ra const float AvatarData::OUT_OF_VIEW_PENALTY = -10.0f; -float AvatarData::_avatarSortCoefficientSize { 1.0f }; -float AvatarData::_avatarSortCoefficientCenter { 0.25 }; +float AvatarData::_avatarSortCoefficientSize { 4.0f }; +float AvatarData::_avatarSortCoefficientCenter { 4.0f }; float AvatarData::_avatarSortCoefficientAge { 1.0f }; QScriptValue AvatarEntityMapToScriptValue(QScriptEngine* engine, const AvatarEntityMap& value) { From 6ac38190c1db0150dca9acd423cbb3dd7f80add6 Mon Sep 17 00:00:00 2001 From: David Back Date: Thu, 6 Sep 2018 12:23:38 -0700 Subject: [PATCH 317/545] tweak scaling multiple --- scripts/system/libraries/entitySelectionTool.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index 2478160293..945f6a88d7 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -437,7 +437,7 @@ SelectionDisplay = (function() { var STRETCH_CUBE_CAMERA_DISTANCE_MULTIPLE = 0.02; var STRETCH_MINIMUM_DIMENSION = 0.001; var STRETCH_ALL_MINIMUM_DIMENSION = 0.01; - var STRETCH_DIRECTION_ALL_CAMERA_DISTANCE_MULTIPLE = 6; + var STRETCH_DIRECTION_ALL_CAMERA_DISTANCE_MULTIPLE = 2; var STRETCH_PANEL_WIDTH = 0.01; var SCALE_EDGE_OFFSET = 0.5; From 90a51e618134faf605074afb2785d0962dfa4121 Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 6 Sep 2018 13:12:48 -0700 Subject: [PATCH 318/545] added walk velocity threshold, this determines if we are in the walk state. when we are then we don't do cg leaning calculation. this will smooth out the walking in a large tracked area --- interface/src/avatar/MyAvatar.cpp | 59 +++++++++++++----------- interface/src/avatar/MyAvatar.h | 2 + interface/src/avatar/MySkeletonModel.cpp | 2 +- libraries/shared/src/AvatarConstants.h | 7 +-- 4 files changed, 39 insertions(+), 31 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 8a29d3f9c7..c8af792d8f 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -516,8 +516,8 @@ void MyAvatar::update(float deltaTime) { head->relax(deltaTime); updateFromTrackers(deltaTime); - if (_isInWalkingState && glm::length(getControllerPoseInAvatarFrame(controller::Action::HEAD).getVelocity()) < 0.15f) { - _isInWalkingState = false; + if (getIsInWalkingState() && glm::length(getControllerPoseInAvatarFrame(controller::Action::HEAD).getVelocity()) < DEFAULT_AVATAR_WALK_SPEED_THRESHOLD) { + setIsInWalkingState(false); } // Get audio loudness data from audio input device @@ -3806,6 +3806,10 @@ float MyAvatar::getUserEyeHeight() const { return userHeight - userHeight * ratio; } +bool MyAvatar::getIsInWalkingState() const { + return _isInWalkingState; +} + float MyAvatar::getWalkSpeed() const { return _walkSpeed.get() * _walkSpeedScalar; } @@ -3822,6 +3826,10 @@ void MyAvatar::setSprintMode(bool sprint) { _walkSpeedScalar = sprint ? _sprintSpeed.get() : AVATAR_WALK_SPEED_SCALAR; } +void MyAvatar::setIsInWalkingState(bool isWalking) { + _isInWalkingState = isWalking; +} + void MyAvatar::setWalkSpeed(float value) { _walkSpeed.set(value); } @@ -4006,37 +4014,38 @@ bool MyAvatar::FollowHelper::shouldActivateHorizontalCG(MyAvatar& myAvatar) cons controller::Pose currentLeftHandPose = myAvatar.getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND); controller::Pose currentRightHandPose = myAvatar.getControllerPoseInAvatarFrame(controller::Action::RIGHT_HAND); - qCDebug(interfaceapp) << "currentVelocity is " < 0.15f) { - myAvatar._isInWalkingState = true; - } - } else { - glm::vec3 defaultHipsPosition = myAvatar.getAbsoluteDefaultJointTranslationInObjectFrame(myAvatar.getJointIndex("Hips")); - glm::vec3 defaultHeadPosition = myAvatar.getAbsoluteDefaultJointTranslationInObjectFrame(myAvatar.getJointIndex("Head")); - glm::vec3 currentHeadPosition = currentHeadPose.getTranslation(); - float anatomicalHeadToHipsDistance = glm::length(defaultHeadPosition - defaultHipsPosition); - if (!isActive(Horizontal) && - (glm::length(currentHeadPosition - defaultHipsPosition) > (anatomicalHeadToHipsDistance + (DEFAULT_AVATAR_SPINE_STRETCH_LIMIT * anatomicalHeadToHipsDistance)))) { - myAvatar.setResetMode(true); - qCDebug(interfaceapp) << "failsafe called, default back " << anatomicalHeadToHipsDistance << " scale " << myAvatar.getAvatarScale() << " current length " << glm::length(currentHeadPosition - defaultHipsPosition); + // a step is detected stepDetected = true; - if (glm::length(currentHeadPose.velocity) > 0.15f) { - myAvatar._isInWalkingState = true; + if (glm::length(currentHeadPose.velocity) > DEFAULT_AVATAR_WALK_SPEED_THRESHOLD) { + myAvatar.setIsInWalkingState(true); + } + } else { + glm::vec3 defaultHipsPosition = myAvatar.getAbsoluteDefaultJointTranslationInObjectFrame(myAvatar.getJointIndex("Hips")); + glm::vec3 defaultHeadPosition = myAvatar.getAbsoluteDefaultJointTranslationInObjectFrame(myAvatar.getJointIndex("Head")); + glm::vec3 currentHeadPosition = currentHeadPose.getTranslation(); + float anatomicalHeadToHipsDistance = glm::length(defaultHeadPosition - defaultHipsPosition); + if (!isActive(Horizontal) && + (glm::length(currentHeadPosition - defaultHipsPosition) > (anatomicalHeadToHipsDistance + (DEFAULT_AVATAR_SPINE_STRETCH_LIMIT * anatomicalHeadToHipsDistance)))) { + myAvatar.setResetMode(true); + stepDetected = true; + if (glm::length(currentHeadPose.velocity) > DEFAULT_AVATAR_WALK_SPEED_THRESHOLD) { + myAvatar.setIsInWalkingState(true); + } } } - qCDebug(interfaceapp) << "current head height " << currentHeadPose.getTranslation().y << " scale " << myAvatar.getAvatarScale() << " anatomical " << anatomicalHeadToHipsDistance; } return stepDetected; } @@ -4053,9 +4062,6 @@ bool MyAvatar::FollowHelper::shouldActivateVertical(const MyAvatar& myAvatar, co void MyAvatar::FollowHelper::prePhysicsUpdate(MyAvatar& myAvatar, const glm::mat4& desiredBodyMatrix, const glm::mat4& currentBodyMatrix, bool hasDriveInput) { - const float VELOCITY_THRESHHOLD = 1.0f; - float currentVelocity = glm::length(myAvatar.getLocalVelocity() / myAvatar.getSensorToWorldScale()); - if (myAvatar.getHMDLeanRecenterEnabled() && qApp->getCamera().getMode() != CAMERA_MODE_MIRROR) { if (!isActive(Rotation) && (shouldActivateRotation(myAvatar, desiredBodyMatrix, currentBodyMatrix) || hasDriveInput)) { @@ -4063,7 +4069,7 @@ void MyAvatar::FollowHelper::prePhysicsUpdate(MyAvatar& myAvatar, const glm::mat myAvatar.setHeadControllerFacingMovingAverage(myAvatar.getHeadControllerFacing()); } if (myAvatar.getCenterOfGravityModelEnabled()) { - if ((!isActive(Horizontal) && (shouldActivateHorizontalCG(myAvatar) || hasDriveInput)) || ( isActive(Horizontal) && (currentVelocity > VELOCITY_THRESHHOLD))) { + if (!isActive(Horizontal) && (shouldActivateHorizontalCG(myAvatar) || hasDriveInput)) { activate(Horizontal); if (myAvatar.getEnableStepResetRotation()) { activate(Rotation); @@ -4089,7 +4095,6 @@ void MyAvatar::FollowHelper::prePhysicsUpdate(MyAvatar& myAvatar, const glm::mat setForceActivateRotation(false); } if (!isActive(Horizontal) && getForceActivateHorizontal()) { - qCDebug(interfaceapp) << "called the recentering from script"; activate(Horizontal); setForceActivateHorizontal(false); } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index aa76e29b14..5008190c33 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -1086,6 +1086,8 @@ public: const QUuid& getSelfID() const { return AVATAR_SELF_ID; } + void setIsInWalkingState(bool isWalking); + bool getIsInWalkingState() const; void setWalkSpeed(float value); float getWalkSpeed() const; void setWalkBackwardSpeed(float value); diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 77d1a87195..3084542472 100644 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -46,7 +46,7 @@ static AnimPose computeHipsInSensorFrame(MyAvatar* myAvatar, bool isFlying) { } glm::mat4 hipsMat; - if (myAvatar->getCenterOfGravityModelEnabled() && !isFlying) { + if (myAvatar->getCenterOfGravityModelEnabled() && !isFlying && !(myAvatar->getIsInWalkingState())) { // then we use center of gravity model hipsMat = myAvatar->deriveBodyUsingCgModel(); } else { diff --git a/libraries/shared/src/AvatarConstants.h b/libraries/shared/src/AvatarConstants.h index 80676b6a51..6c38d08c96 100644 --- a/libraries/shared/src/AvatarConstants.h +++ b/libraries/shared/src/AvatarConstants.h @@ -25,9 +25,9 @@ const float DEFAULT_AVATAR_SUPPORT_BASE_RIGHT = 0.25f; const float DEFAULT_AVATAR_SUPPORT_BASE_FRONT = -0.20f; const float DEFAULT_AVATAR_SUPPORT_BASE_BACK = 0.12f; const float DEFAULT_AVATAR_LATERAL_STEPPING_THRESHOLD = 0.10f; -const float DEFAULT_AVATAR_ANTERIOR_STEPPING_THRESHOLD = 0.07f; -const float DEFAULT_AVATAR_POSTERIOR_STEPPING_THRESHOLD = 0.06f; -const float DEFAULT_AVATAR_HEAD_ANGULAR_VELOCITY_STEPPING_THRESHOLD = 0.4f; +const float DEFAULT_AVATAR_ANTERIOR_STEPPING_THRESHOLD = 0.04f; +const float DEFAULT_AVATAR_POSTERIOR_STEPPING_THRESHOLD = 0.05f; +const float DEFAULT_AVATAR_HEAD_ANGULAR_VELOCITY_STEPPING_THRESHOLD = 0.3f; const float DEFAULT_AVATAR_MODE_HEIGHT_STEPPING_THRESHOLD = -0.02f; const float DEFAULT_HANDS_VELOCITY_DIRECTION_STEPPING_THRESHOLD = 0.4f; const float DEFAULT_HANDS_ANGULAR_VELOCITY_STEPPING_THRESHOLD = 3.3f; @@ -68,6 +68,7 @@ const glm::quat DEFAULT_AVATAR_RIGHTFOOT_ROT { -0.4016716778278351f, 0.915461599 const float DEFAULT_AVATAR_MAX_WALKING_SPEED = 2.6f; // meters / second const float DEFAULT_AVATAR_MAX_WALKING_BACKWARD_SPEED = 2.2f; // meters / second const float DEFAULT_AVATAR_MAX_FLYING_SPEED = 30.0f; // meters / second +const float DEFAULT_AVATAR_WALK_SPEED_THRESHOLD = 0.15f; const float DEFAULT_AVATAR_GRAVITY = -5.0f; // meters / second^2 const float DEFAULT_AVATAR_JUMP_SPEED = 3.5f; // meters / second From c986d55d8b9050eda0c1a48031ccd62d5f3ac5e1 Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 6 Sep 2018 13:18:54 -0700 Subject: [PATCH 319/545] removed step script from repo --- scripts/developer/objectOrientedStep.js | 688 ------------------------ 1 file changed, 688 deletions(-) delete mode 100644 scripts/developer/objectOrientedStep.js diff --git a/scripts/developer/objectOrientedStep.js b/scripts/developer/objectOrientedStep.js deleted file mode 100644 index a5c27e36b9..0000000000 --- a/scripts/developer/objectOrientedStep.js +++ /dev/null @@ -1,688 +0,0 @@ -/* jslint bitwise: true */ - -/* global Script, Vec3, MyAvatar, Tablet, Messages, Quat, -DebugDraw, Mat4, Entities, Xform, Controller, Camera, console, document*/ - -Script.registerValue("STEPAPP", true); -var CENTIMETERSPERMETER = 100.0; -var LEFT = 0; -var RIGHT = 1; -var INCREASING = 1.0; -var DECREASING = -1.0; -var DEFAULT_AVATAR_HEIGHT = 1.64; -var TABLET_BUTTON_NAME = "STEP"; -var CHANGE_OF_BASIS_ROTATION = { x: 0, y: 1, z: 0, w: 0 }; -// in meters (mostly) -var DEFAULT_ANTERIOR = 0.04; -var DEFAULT_POSTERIOR = 0.06; -var DEFAULT_LATERAL = 0.10; -var DEFAULT_HEIGHT_DIFFERENCE = 0.02; -var DEFAULT_ANGULAR_VELOCITY = 0.3; -var DEFAULT_HAND_VELOCITY = 0.4; -var DEFAULT_ANGULAR_HAND_VELOCITY = 3.3; -var DEFAULT_HEAD_VELOCITY = 0.14; -var DEFAULT_LEVEL_PITCH = 7; -var DEFAULT_LEVEL_ROLL = 7; -var DEFAULT_DIFF = 0.0; -var DEFAULT_DIFF_EULERS = { x: 0.0, y: 0.0, z: 0.0 }; -var DEFAULT_HIPS_POSITION; -var DEFAULT_HEAD_POSITION; -var DEFAULT_TORSO_LENGTH; -var SPINE_STRETCH_LIMIT = 0.02; - -var VELOCITY_EPSILON = 0.02; -var AVERAGING_RATE = 0.03; -var HEIGHT_AVERAGING_RATE = 0.01; -var STEP_TIME_SECS = 0.2; -var MODE_SAMPLE_LENGTH = 100; -var RESET_MODE = false; -var HEAD_TURN_THRESHOLD = 25.0; -var NO_SHARED_DIRECTION = -0.98; -var LOADING_DELAY = 500; -var FAILSAFE_TIMEOUT = 2.5; - -var debugDrawBase = true; -var activated = false; -var documentLoaded = false; -var failsafeFlag = false; -var failsafeSignalTimer = -1.0; -var stepTimer = -1.0; - - -var modeArray = new Array(MODE_SAMPLE_LENGTH); -var modeHeight = -10.0; - -var handPosition; -var handOrientation; -var hands = []; -var hipToHandAverage = []; -var handDotHead = []; -var headAverageOrientation = MyAvatar.orientation; -var headPoseAverageOrientation = { x: 0, y: 0, z: 0, w: 1 }; -var averageHeight = 1.0; -var headEulers = { x: 0.0, y: 0.0, z: 0.0 }; -var headAverageEulers = { x: 0.0, y: 0.0, z: 0.0 }; -var headAveragePosition = { x: 0, y: 0.4, z: 0 }; -var frontLeft = { x: -DEFAULT_LATERAL, y: 0, z: -DEFAULT_ANTERIOR }; -var frontRight = { x: DEFAULT_LATERAL, y: 0, z: -DEFAULT_ANTERIOR }; -var backLeft = { x: -DEFAULT_LATERAL, y: 0, z: DEFAULT_POSTERIOR }; -var backRight = { x: DEFAULT_LATERAL, y: 0, z: DEFAULT_POSTERIOR }; - - -// define state readings constructor -function StateReading(headPose, rhandPose, lhandPose, backLength, diffFromMode, diffFromAverageHeight, diffFromAveragePosition, - diffFromAverageEulers) { - this.headPose = headPose; - this.rhandPose = rhandPose; - this.lhandPose = lhandPose; - this.backLength = backLength; - this.diffFromMode = diffFromMode; - this.diffFromAverageHeight = diffFromAverageHeight; - this.diffFromAveragePosition = diffFromAveragePosition; - this.diffFromAverageEulers = diffFromAverageEulers; -} - -// define current state readings object for holding tracker readings and current differences from averages -var currentStateReadings = new StateReading(Controller.getPoseValue(Controller.Standard.Head), - Controller.getPoseValue(Controller.Standard.RightHand), Controller.getPoseValue(Controller.Standard.LeftHand), - DEFAULT_TORSO_LENGTH, DEFAULT_DIFF, DEFAULT_DIFF, DEFAULT_DIFF, DEFAULT_DIFF_EULERS); - -// declare the checkbox constructor -function AppCheckbox(type,id,eventType,isChecked) { - this.type = type; - this.id = id; - this.eventType = eventType; - this.data = {value: isChecked}; -} - -// define the checkboxes in the html file -var usingAverageHeight = new AppCheckbox("checkboxtick", "runningAverageHeightCheck", "onRunningAverageHeightCheckBox", - false); -var usingModeHeight = new AppCheckbox("checkboxtick","modeCheck","onModeCheckBox",true); -var usingBaseOfSupport = new AppCheckbox("checkboxtick","baseOfSupportCheck","onBaseOfSupportCheckBox",true); -var usingAverageHeadPosition = new AppCheckbox("checkboxtick", "headAveragePositionCheck", "onHeadAveragePositionCheckBox", - false); - -var checkBoxArray = new Array(usingAverageHeight,usingModeHeight,usingBaseOfSupport,usingAverageHeadPosition); - -// declare the html slider constructor -function AppProperty(name, type, eventType, signalType, setFunction, initValue, convertToThreshold, convertToSlider, signalOn) { - this.name = name; - this.type = type; - this.eventType = eventType; - this.signalType = signalType; - this.setValue = setFunction; - this.value = initValue; - this.get = function () { - return this.value; - }; - this.convertToThreshold = convertToThreshold; - this.convertToSlider = convertToSlider; - this.signalOn = signalOn; -} - -// define the sliders -var frontBaseProperty = new AppProperty("#anteriorBase-slider", "slider", "onAnteriorBaseSlider", "frontSignal", - setAnteriorDistance, DEFAULT_ANTERIOR, function (num) { - return convertToMeters(num); - }, function (num) { - return convertToCentimeters(num); - },true); -var backBaseProperty = new AppProperty("#posteriorBase-slider", "slider", "onPosteriorBaseSlider", "backSignal", - setPosteriorDistance, DEFAULT_POSTERIOR, function (num) { - return convertToMeters(num); - }, function (num) { - return convertToCentimeters(num); - }, true); -var lateralBaseProperty = new AppProperty("#lateralBase-slider", "slider", "onLateralBaseSlider", "lateralSignal", - setLateralDistance, DEFAULT_LATERAL, function (num) { - return convertToMeters(num); - }, function (num) { - return convertToCentimeters(num); - }, true); -var headAngularVelocityProperty = new AppProperty("#angularVelocityHead-slider", "slider", "onAngularVelocitySlider", - "angularHeadSignal", setAngularThreshold, DEFAULT_ANGULAR_VELOCITY, function (num) { - var base = 4; - var shift = 2; - return convertExponential(base, num, DECREASING, shift); - }, function (num) { - var base = 4; - var shift = 2; - return convertLog(base, num, DECREASING, shift); - }, true); -var heightDifferenceProperty = new AppProperty("#heightDifference-slider", "slider", "onHeightDifferenceSlider", "heightSignal", - setHeightThreshold, DEFAULT_HEIGHT_DIFFERENCE, function (num) { - return convertToMeters(-num); - }, function (num) { - return convertToCentimeters(-num); - }, true); -var handsVelocityProperty = new AppProperty("#handsVelocity-slider", "slider", "onHandsVelocitySlider", "handVelocitySignal", - setHandVelocityThreshold, DEFAULT_HAND_VELOCITY, function (num) { - return num; - }, function (num) { - return num; - }, true); -var handsAngularVelocityProperty = new AppProperty("#handsAngularVelocity-slider", "slider", "onHandsAngularVelocitySlider", - "handAngularSignal", setHandAngularVelocityThreshold, DEFAULT_ANGULAR_HAND_VELOCITY, function (num) { - var base = 7; - var shift = 2; - return convertExponential(base, num, DECREASING, shift); - }, function (num) { - var base = 7; - var shift = 2; - return convertLog(base, num, DECREASING, shift); - }, true); -var headVelocityProperty = new AppProperty("#headVelocity-slider", "slider", "onHeadVelocitySlider", "headVelocitySignal", - setHeadVelocityThreshold, DEFAULT_HEAD_VELOCITY, function (num) { - var base = 2; - var shift = 0; - return convertExponential(base, num, INCREASING, shift); - }, function (num) { - var base = 2; - var shift = 0; - return convertLog(base, num, INCREASING, shift); - }, true); -var headPitchProperty = new AppProperty("#headPitch-slider", "slider", "onHeadPitchSlider", "headPitchSignal", - setHeadPitchThreshold, DEFAULT_LEVEL_PITCH, function (num) { - var base = 2.5; - var shift = 5; - return convertExponential(base, num, DECREASING, shift); - }, function (num) { - var base = 2.5; - var shift = 5; - return convertLog(base, num, DECREASING, shift); - }, true); -var headRollProperty = new AppProperty("#headRoll-slider", "slider", "onHeadRollSlider", "headRollSignal", setHeadRollThreshold, - DEFAULT_LEVEL_ROLL, function (num) { - var base = 2.5; - var shift = 5; - return convertExponential(base, num, DECREASING, shift); - }, function (num) { - var base = 2.5; - var shift = 5; - return convertLog(base, num, DECREASING, shift); - }, true); - -var propArray = new Array(frontBaseProperty, backBaseProperty, lateralBaseProperty, headAngularVelocityProperty, - heightDifferenceProperty, handsVelocityProperty, handsAngularVelocityProperty, headVelocityProperty, headPitchProperty, - headRollProperty); - -// var HTML_URL = Script.resolvePath("http://hifi-content.s3.amazonaws.com/angus/stepApp/stepApp.html"); -var HTML_URL = Script.resolvePath("http://hifi-content.s3.amazonaws.com/angus/stepApp/stepAppExtra.html"); -var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system"); - -function manageClick() { - if (activated) { - tablet.gotoHomeScreen(); - } else { - tablet.gotoWebScreen(HTML_URL); - } -} - -var tabletButton = tablet.addButton({ - text: TABLET_BUTTON_NAME, - icon: Script.resolvePath("http://hifi-content.s3.amazonaws.com/angus/stepApp/foot.svg"), - activeIcon: Script.resolvePath("http://hifi-content.s3.amazonaws.com/angus/stepApp/foot.svg") -}); - -function drawBase() { - // transform corners into world space, for rendering. - var worldPointLf = Vec3.sum(MyAvatar.position,Vec3.multiplyQbyV(MyAvatar.orientation, frontLeft)); - var worldPointRf = Vec3.sum(MyAvatar.position,Vec3.multiplyQbyV(MyAvatar.orientation, frontRight)); - var worldPointLb = Vec3.sum(MyAvatar.position,Vec3.multiplyQbyV(MyAvatar.orientation, backLeft)); - var worldPointRb = Vec3.sum(MyAvatar.position,Vec3.multiplyQbyV(MyAvatar.orientation, backRight)); - - var GREEN = { r: 0, g: 1, b: 0, a: 1 }; - // draw border - DebugDraw.drawRay(worldPointLf, worldPointRf, GREEN); - DebugDraw.drawRay(worldPointRf, worldPointRb, GREEN); - DebugDraw.drawRay(worldPointRb, worldPointLb, GREEN); - DebugDraw.drawRay(worldPointLb, worldPointLf, GREEN); -} - -function onKeyPress(event) { - if (event.text === "'") { - // when the sensors are reset, then reset the mode. - RESET_MODE = false; - } -} - -function onWebEventReceived(msg) { - var message = JSON.parse(msg); - print(" we have a message from html dialog " + message.type); - propArray.forEach(function (prop) { - if (prop.eventType === message.type) { - prop.setValue(prop.convertToThreshold(message.data.value)); - print("message from " + prop.name); - // break; - } - }); - checkBoxArray.forEach(function(cbox) { - if (cbox.eventType === message.type) { - cbox.data.value = message.data.value; - // break; - } - }); - if (message.type === "onCreateStepApp") { - print("document loaded"); - documentLoaded = true; - Script.setTimeout(initAppForm, LOADING_DELAY); - } -} - -function initAppForm() { - print("step app is loaded: " + documentLoaded); - if (documentLoaded === true) { - propArray.forEach(function (prop) { - tablet.emitScriptEvent(JSON.stringify({ - "type": "trigger", - "id": prop.signalType, - "data": { "value": "green" } - })); - tablet.emitScriptEvent(JSON.stringify({ - "type": "slider", - "id": prop.name, - "data": { "value": prop.convertToSlider(prop.value) } - })); - }); - checkBoxArray.forEach(function (cbox) { - tablet.emitScriptEvent(JSON.stringify({ - "type": "checkboxtick", - "id": cbox.id, - "data": { "value": cbox.data.value } - })); - }); - } -} - -function updateSignalColors() { - - // force the updates by running the threshold comparisons - withinBaseOfSupport(currentStateReadings.headPose.translation); - withinThresholdOfStandingHeightMode(currentStateReadings.diffFromMode); - headAngularVelocityBelowThreshold(currentStateReadings.headPose.angularVelocity); - handDirectionMatchesHeadDirection(currentStateReadings.lhandPose, currentStateReadings.rhandPose); - handAngularVelocityBelowThreshold(currentStateReadings.lhandPose, currentStateReadings.rhandPose); - headVelocityGreaterThanThreshold(Vec3.length(currentStateReadings.headPose.velocity)); - headMovedAwayFromAveragePosition(currentStateReadings.diffFromAveragePosition); - headLowerThanHeightAverage(currentStateReadings.diffFromAverageHeight); - isHeadLevel(currentStateReadings.diffFromAverageEulers); - - propArray.forEach(function (prop) { - if (prop.signalOn) { - tablet.emitScriptEvent(JSON.stringify({ "type": "trigger", "id": prop.signalType, "data": { "value": "green" } })); - } else { - tablet.emitScriptEvent(JSON.stringify({ "type": "trigger", "id": prop.signalType, "data": { "value": "red" } })); - } - }); -} - -function onScreenChanged(type, url) { - print("Screen changed"); - if (type === "Web" && url === HTML_URL) { - if (!activated) { - // hook up to event bridge - tablet.webEventReceived.connect(onWebEventReceived); - print("after connect web event"); - MyAvatar.hmdLeanRecenterEnabled = false; - - } - activated = true; - } else { - if (activated) { - // disconnect from event bridge - tablet.webEventReceived.disconnect(onWebEventReceived); - documentLoaded = false; - } - activated = false; - } -} - -function getLog(x, y) { - return Math.log(y) / Math.log(x); -} - -function noConversion(num) { - return num; -} - -function convertLog(base, num, direction, shift) { - return direction * getLog(base, (num + 1.0)) + shift; -} - -function convertExponential(base, num, direction, shift) { - return Math.pow(base, (direction*num + shift)) - 1.0; -} - -function convertToCentimeters(num) { - return num * CENTIMETERSPERMETER; -} - -function convertToMeters(num) { - print("convert to meters " + num); - return num / CENTIMETERSPERMETER; -} - -function isInsideLine(a, b, c) { - return (((b.x - a.x)*(c.z - a.z) - (b.z - a.z)*(c.x - a.x)) > 0); -} - -function setAngularThreshold(num) { - headAngularVelocityProperty.value = num; - print("angular threshold " + headAngularVelocityProperty.get()); -} - -function setHeadRollThreshold(num) { - headRollProperty.value = num; - print("head roll threshold " + headRollProperty.get()); -} - -function setHeadPitchThreshold(num) { - headPitchProperty.value = num; - print("head pitch threshold " + headPitchProperty.get()); -} - -function setHeightThreshold(num) { - heightDifferenceProperty.value = num; - print("height threshold " + heightDifferenceProperty.get()); -} - -function setLateralDistance(num) { - lateralBaseProperty.value = num; - frontLeft.x = -lateralBaseProperty.get(); - frontRight.x = lateralBaseProperty.get(); - backLeft.x = -lateralBaseProperty.get(); - backRight.x = lateralBaseProperty.get(); - print("lateral distance " + lateralBaseProperty.get()); -} - -function setAnteriorDistance(num) { - frontBaseProperty.value = num; - frontLeft.z = -frontBaseProperty.get(); - frontRight.z = -frontBaseProperty.get(); - print("anterior distance " + frontBaseProperty.get()); -} - -function setPosteriorDistance(num) { - backBaseProperty.value = num; - backLeft.z = backBaseProperty.get(); - backRight.z = backBaseProperty.get(); - print("posterior distance " + backBaseProperty.get()); -} - -function setHandAngularVelocityThreshold(num) { - handsAngularVelocityProperty.value = num; - print("hand angular velocity threshold " + handsAngularVelocityProperty.get()); -} - -function setHandVelocityThreshold(num) { - handsVelocityProperty.value = num; - print("hand velocity threshold " + handsVelocityProperty.get()); -} - -function setHeadVelocityThreshold(num) { - headVelocityProperty.value = num; - print("headvelocity threshold " + headVelocityProperty.get()); -} - -function withinBaseOfSupport(pos) { - var userScale = 1.0; - frontBaseProperty.signalOn = !(isInsideLine(Vec3.multiply(userScale, frontLeft), Vec3.multiply(userScale, frontRight), pos)); - backBaseProperty.signalOn = !(isInsideLine(Vec3.multiply(userScale, backRight), Vec3.multiply(userScale, backLeft), pos)); - lateralBaseProperty.signalOn = !(isInsideLine(Vec3.multiply(userScale, frontRight), Vec3.multiply(userScale, backRight), pos) - && isInsideLine(Vec3.multiply(userScale, backLeft), Vec3.multiply(userScale, frontLeft), pos)); - return (!frontBaseProperty.signalOn && !backBaseProperty.signalOn && !lateralBaseProperty.signalOn); -} - -function withinThresholdOfStandingHeightMode(heightDiff) { - if (usingModeHeight.data.value) { - heightDifferenceProperty.signalOn = heightDiff < heightDifferenceProperty.get(); - return heightDifferenceProperty.signalOn; - } else { - return true; - } -} - -function headAngularVelocityBelowThreshold(headAngularVelocity) { - var angVel = Vec3.length({ x: headAngularVelocity.x, y: 0, z: headAngularVelocity.z }); - headAngularVelocityProperty.signalOn = angVel < headAngularVelocityProperty.get(); - return headAngularVelocityProperty.signalOn; -} - -function handDirectionMatchesHeadDirection(lhPose, rhPose) { - handsVelocityProperty.signalOn = ((handsVelocityProperty.get() < NO_SHARED_DIRECTION) || - ((!lhPose.valid || ((handDotHead[LEFT] > handsVelocityProperty.get()) && - (Vec3.length(lhPose.velocity) > VELOCITY_EPSILON))) && - (!rhPose.valid || ((handDotHead[RIGHT] > handsVelocityProperty.get()) && - (Vec3.length(rhPose.velocity) > VELOCITY_EPSILON))))); - return handsVelocityProperty.signalOn; -} - -function handAngularVelocityBelowThreshold(lhPose, rhPose) { - var xzRHandAngularVelocity = Vec3.length({ x: rhPose.angularVelocity.x, y: 0.0, z: rhPose.angularVelocity.z }); - var xzLHandAngularVelocity = Vec3.length({ x: lhPose.angularVelocity.x, y: 0.0, z: lhPose.angularVelocity.z }); - handsAngularVelocityProperty.signalOn = ((!rhPose.valid ||(xzRHandAngularVelocity < handsAngularVelocityProperty.get())) - && (!lhPose.valid || (xzLHandAngularVelocity < handsAngularVelocityProperty.get()))); - return handsAngularVelocityProperty.signalOn; -} - -function headVelocityGreaterThanThreshold(headVel) { - headVelocityProperty.signalOn = (headVel > headVelocityProperty.get()) || (headVelocityProperty.get() < VELOCITY_EPSILON); - return headVelocityProperty.signalOn; -} - -function headMovedAwayFromAveragePosition(headDelta) { - return !withinBaseOfSupport(headDelta) || !usingAverageHeadPosition.data.value; -} - -function headLowerThanHeightAverage(heightDiff) { - if (usingAverageHeight.data.value) { - print("head lower than height average"); - heightDifferenceProperty.signalOn = heightDiff < heightDifferenceProperty.get(); - return heightDifferenceProperty.signalOn; - } else { - return true; - } -} - -function isHeadLevel(diffEulers) { - headRollProperty.signalOn = Math.abs(diffEulers.z) < headRollProperty.get(); - headPitchProperty.signalOn = Math.abs(diffEulers.x) < headPitchProperty.get(); - return (headRollProperty.signalOn && headPitchProperty.signalOn); -} - -function findAverage(arr) { - var sum = arr.reduce(function (acc, val) { - return acc + val; - },0); - return sum / arr.length; -} - -function addToModeArray(arr,num) { - for (var i = 0 ;i < (arr.length - 1); i++) { - arr[i] = arr[i+1]; - } - arr[arr.length - 1] = (Math.floor(num*CENTIMETERSPERMETER))/CENTIMETERSPERMETER; -} - -function findMode(ary, currentMode, backLength, defaultBack, currentHeight) { - var numMapping = {}; - var greatestFreq = 0; - var mode; - ary.forEach(function (number) { - numMapping[number] = (numMapping[number] || 0) + 1; - if ((greatestFreq < numMapping[number]) || ((numMapping[number] === MODE_SAMPLE_LENGTH) && (number > currentMode) )) { - greatestFreq = numMapping[number]; - mode = number; - } - }); - if (mode > currentMode) { - return Number(mode); - } else { - if (!RESET_MODE && HMD.active) { - print("resetting the mode............................................. "); - print("resetting the mode............................................. "); - RESET_MODE = true; - var correction = 0.02; - return currentHeight - correction; - } else { - return currentMode; - } - } -} - -function update(dt) { - if (debugDrawBase) { - drawBase(); - } - // Update current state information - currentStateReadings.headPose = Controller.getPoseValue(Controller.Standard.Head); - currentStateReadings.rhandPose = Controller.getPoseValue(Controller.Standard.RightHand); - currentStateReadings.lhandPose = Controller.getPoseValue(Controller.Standard.LeftHand); - - // back length - var headMinusHipLean = Vec3.subtract(currentStateReadings.headPose.translation, DEFAULT_HIPS_POSITION); - currentStateReadings.backLength = Vec3.length(headMinusHipLean); - // print("back length and default " + currentStateReadings.backLength + " " + DEFAULT_TORSO_LENGTH); - - // mode height - addToModeArray(modeArray, currentStateReadings.headPose.translation.y); - modeHeight = findMode(modeArray, modeHeight, currentStateReadings.backLength, DEFAULT_TORSO_LENGTH, - currentStateReadings.headPose.translation.y); - currentStateReadings.diffFromMode = modeHeight - currentStateReadings.headPose.translation.y; - - // hand direction - var leftHandLateralPoseVelocity = currentStateReadings.lhandPose.velocity; - leftHandLateralPoseVelocity.y = 0.0; - var rightHandLateralPoseVelocity = currentStateReadings.rhandPose.velocity; - rightHandLateralPoseVelocity.y = 0.0; - var headLateralPoseVelocity = currentStateReadings.headPose.velocity; - headLateralPoseVelocity.y = 0.0; - handDotHead[LEFT] = Vec3.dot(Vec3.normalize(leftHandLateralPoseVelocity), Vec3.normalize(headLateralPoseVelocity)); - handDotHead[RIGHT] = Vec3.dot(Vec3.normalize(rightHandLateralPoseVelocity), Vec3.normalize(headLateralPoseVelocity)); - - // average head position - headAveragePosition = Vec3.mix(headAveragePosition, currentStateReadings.headPose.translation, AVERAGING_RATE); - currentStateReadings.diffFromAveragePosition = Vec3.subtract(currentStateReadings.headPose.translation, - headAveragePosition); - - // average height - averageHeight = currentStateReadings.headPose.translation.y * HEIGHT_AVERAGING_RATE + - averageHeight * (1.0 - HEIGHT_AVERAGING_RATE); - currentStateReadings.diffFromAverageHeight = Math.abs(currentStateReadings.headPose.translation.y - averageHeight); - - // eulers diff - headEulers = Quat.safeEulerAngles(currentStateReadings.headPose.rotation); - headAverageOrientation = Quat.slerp(headAverageOrientation, currentStateReadings.headPose.rotation, AVERAGING_RATE); - headAverageEulers = Quat.safeEulerAngles(headAverageOrientation); - currentStateReadings.diffFromAverageEulers = Vec3.subtract(headAverageEulers, headEulers); - - // headpose rig space is for determining when to recenter rotation. - var headPoseRigSpace = Quat.multiply(CHANGE_OF_BASIS_ROTATION, currentStateReadings.headPose.rotation); - headPoseAverageOrientation = Quat.slerp(headPoseAverageOrientation, headPoseRigSpace, AVERAGING_RATE); - var headPoseAverageEulers = Quat.safeEulerAngles(headPoseAverageOrientation); - - // make the signal colors reflect the current thresholds that have been crossed - updateSignalColors(); - - SPINE_STRETCH_LIMIT = (0.04) * DEFAULT_TORSO_LENGTH * MyAvatar.scale; - - //print("the spine stretch limit is " + SPINE_STRETCH_LIMIT + " head avatar space is " + currentStateReadings.headPose.translation.y); - //print("the current back length is " + currentStateReadings.backLength + " " + DEFAULT_TORSO_LENGTH); - // Conditions for taking a step. - // 1. off the base of support. front, lateral, back edges. - // 2. head is not lower than the height mode value by more than the maxHeightChange tolerance - // 3. the angular velocity of the head is not greater than the threshold value - // ie this reflects the speed the head is rotating away from having up = (0,1,0) in Avatar frame.. - // 4. the hands velocity vector has the same direction as the head, within the given tolerance - // the tolerance is an acos value, -1 means the hands going in any direction will not block translating - // up to 1 where the hands velocity direction must exactly match that of the head. -1 threshold disables this condition. - // 5. the angular velocity xz magnitude for each hand is below the threshold value - // ie here this reflects the speed that each hand is rotating away from having up = (0,1,0) in Avatar frame. - // 6. head velocity is below step threshold - // 7. head has moved further than the threshold from the running average position of the head. - // 8. head height is not lower than the running average head height with a difference of maxHeightChange. - // 9. head's rotation in avatar space is not pitching or rolling greater than the pitch or roll thresholds - if (!withinBaseOfSupport(currentStateReadings.headPose.translation) && - withinThresholdOfStandingHeightMode(currentStateReadings.diffFromMode) && - headAngularVelocityBelowThreshold(currentStateReadings.headPose.angularVelocity) && - handDirectionMatchesHeadDirection(currentStateReadings.lhandPose, currentStateReadings.rhandPose) && - handAngularVelocityBelowThreshold(currentStateReadings.lhandPose, currentStateReadings.rhandPose) && - headVelocityGreaterThanThreshold(Vec3.length(currentStateReadings.headPose.velocity)) && - headMovedAwayFromAveragePosition(currentStateReadings.diffFromAveragePosition) && - headLowerThanHeightAverage(currentStateReadings.diffFromAverageHeight) && - isHeadLevel(currentStateReadings.diffFromAverageEulers)) { - - if (stepTimer < 0.0) { //!MyAvatar.isRecenteringHorizontally() - print("trigger recenter========================================================"); - MyAvatar.triggerHorizontalRecenter(); - stepTimer = STEP_TIME_SECS; - } - } else if ((currentStateReadings.backLength > (DEFAULT_TORSO_LENGTH + SPINE_STRETCH_LIMIT)) && - (failsafeSignalTimer < 0.0) && HMD.active) { - // do the failsafe recenter. - // failsafeFlag stops repeated setting of failsafe button color. - // RESET_MODE false forces a reset of the height - RESET_MODE = false; - failsafeFlag = true; - failsafeSignalTimer = FAILSAFE_TIMEOUT; - MyAvatar.triggerHorizontalRecenter(); - tablet.emitScriptEvent(JSON.stringify({ "type": "failsafe", "id": "failsafeSignal", "data": { "value": "green" } })); - // in fail safe we debug print the values that were blocking us. - print("failsafe debug---------------------------------------------------------------"); - propArray.forEach(function (prop) { - print(prop.name); - if (!prop.signalOn) { - print(prop.signalType + " contributed to failsafe call"); - } - }); - print("end failsafe debug---------------------------------------------------------------"); - - } - - if ((failsafeSignalTimer < 0.0) && failsafeFlag) { - failsafeFlag = false; - tablet.emitScriptEvent(JSON.stringify({ "type": "failsafe", "id": "failsafeSignal", "data": { "value": "orange" } })); - } - - stepTimer -= dt; - failsafeSignalTimer -= dt; - - if (!HMD.active) { - RESET_MODE = false; - } - - if (Math.abs(headPoseAverageEulers.y) > HEAD_TURN_THRESHOLD) { - // Turn feet - // MyAvatar.triggerRotationRecenter(); - // headPoseAverageOrientation = { x: 0, y: 0, z: 0, w: 1 }; - } -} - -function shutdownTabletApp() { - // GlobalDebugger.stop(); - tablet.removeButton(tabletButton); - if (activated) { - tablet.webEventReceived.disconnect(onWebEventReceived); - tablet.gotoHomeScreen(); - } - tablet.screenChanged.disconnect(onScreenChanged); -} - -tabletButton.clicked.connect(manageClick); -tablet.screenChanged.connect(onScreenChanged); - -Script.setTimeout(function() { - DEFAULT_HIPS_POSITION = MyAvatar.getAbsoluteDefaultJointTranslationInObjectFrame(MyAvatar.getJointIndex("Hips")); - DEFAULT_HEAD_POSITION = MyAvatar.getAbsoluteDefaultJointTranslationInObjectFrame(MyAvatar.getJointIndex("Head")); - DEFAULT_TORSO_LENGTH = Vec3.length(Vec3.subtract(DEFAULT_HEAD_POSITION, DEFAULT_HIPS_POSITION)); - SPINE_STRETCH_LIMIT = (0.04) * DEFAULT_TORSO_LENGTH * MyAvatar.scale; -},(4*LOADING_DELAY)); - -Script.update.connect(update); -Controller.keyPressEvent.connect(onKeyPress); -Script.scriptEnding.connect(function () { - MyAvatar.hmdLeanRecenterEnabled = true; - Script.update.disconnect(update); - shutdownTabletApp(); -}); From 2d2a4804f7790f41a8b9af373c5274ff73e7c84c Mon Sep 17 00:00:00 2001 From: Gabriel Calero Date: Thu, 6 Sep 2018 17:49:52 -0300 Subject: [PATCH 320/545] Add android settings screen. Add AEC setting --- android/app/src/main/AndroidManifest.xml | 10 +++ android/app/src/main/cpp/native.cpp | 46 ++++++++++++++ .../hifiinterface/InterfaceActivity.java | 7 +++ .../hifiinterface/MainActivity.java | 23 +++++++ .../fragment/SettingsFragment.java | 63 +++++++++++++++++++ .../receiver/HeadsetStateReceiver.java | 20 ++++++ .../app/src/main/res/menu/menu_navigation.xml | 5 ++ android/app/src/main/res/values/strings.xml | 5 ++ android/app/src/main/res/xml/settings.xml | 11 ++++ interface/src/AndroidHelper.cpp | 17 +++++ interface/src/AndroidHelper.h | 1 + libraries/audio-client/src/AudioClient.cpp | 6 +- libraries/audio-client/src/AudioClient.h | 8 +++ 13 files changed, 220 insertions(+), 2 deletions(-) create mode 100644 android/app/src/main/java/io/highfidelity/hifiinterface/fragment/SettingsFragment.java create mode 100644 android/app/src/main/java/io/highfidelity/hifiinterface/receiver/HeadsetStateReceiver.java create mode 100644 android/app/src/main/res/xml/settings.xml diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 7255e1f295..b216819ed0 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -9,6 +9,7 @@ + @@ -75,6 +76,15 @@ android:enabled="true" android:exported="false" android:process=":breakpad_uploader"/> + + + + + + diff --git a/android/app/src/main/cpp/native.cpp b/android/app/src/main/cpp/native.cpp index ce5af01f29..6b44b2dc7a 100644 --- a/android/app/src/main/cpp/native.cpp +++ b/android/app/src/main/cpp/native.cpp @@ -355,5 +355,51 @@ JNIEXPORT void Java_io_highfidelity_hifiinterface_WebViewActivity_nativeProcessU AndroidHelper::instance().processURL(QString::fromUtf8(nativeString)); } +JNIEXPORT void JNICALL +Java_io_highfidelity_hifiinterface_fragment_SettingsFragment_updateHifiSetting(JNIEnv *env, + jobject instance, + jstring group_, + jstring key_, + jboolean value_) { + const char *c_group = env->GetStringUTFChars(group_, 0); + const char *c_key = env->GetStringUTFChars(key_, 0); + + const QString group = QString::fromUtf8(c_group); + const QString key = QString::fromUtf8(c_key); + + env->ReleaseStringUTFChars(group_, c_group); + env->ReleaseStringUTFChars(key_, c_key); + + bool value = value_; + + Setting::Handle setting { QStringList() << group << key , !value }; + setting.set(value); +} + +JNIEXPORT jboolean JNICALL +Java_io_highfidelity_hifiinterface_fragment_SettingsFragment_getHifiSettingBoolean(JNIEnv *env, + jobject instance, + jstring group_, + jstring key_, + jboolean defaultValue) { + const char *c_group = env->GetStringUTFChars(group_, 0); + const char *c_key = env->GetStringUTFChars(key_, 0); + + const QString group = QString::fromUtf8(c_group); + const QString key = QString::fromUtf8(c_key); + + env->ReleaseStringUTFChars(group_, c_group); + env->ReleaseStringUTFChars(key_, c_key); + + Setting::Handle setting { QStringList() << group << key , defaultValue}; + return setting.get(); +} + +JNIEXPORT void JNICALL +Java_io_highfidelity_hifiinterface_receiver_HeadsetStateReceiver_notifyHeadsetOn(JNIEnv *env, + jobject instance, + jboolean pluggedIn) { + AndroidHelper::instance().notifyHeadsetOn(pluggedIn); +} } diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java index f161783d6a..08e66a2f42 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/InterfaceActivity.java @@ -13,6 +13,7 @@ package io.highfidelity.hifiinterface; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.content.pm.ActivityInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; @@ -40,6 +41,7 @@ import java.util.HashMap; import java.util.List; import io.highfidelity.hifiinterface.fragment.WebViewFragment; +import io.highfidelity.hifiinterface.receiver.HeadsetStateReceiver; /*import com.google.vr.cardboard.DisplaySynchronizer; import com.google.vr.cardboard.DisplayUtils; @@ -55,6 +57,7 @@ public class InterfaceActivity extends QtActivity implements WebViewFragment.OnW private static final int NORMAL_DPI = 160; private Vibrator mVibrator; + private HeadsetStateReceiver headsetStateReceiver; //public static native void handleHifiURL(String hifiURLString); private native long nativeOnCreate(InterfaceActivity instance, AssetManager assetManager); @@ -151,6 +154,8 @@ public class InterfaceActivity extends QtActivity implements WebViewFragment.OnW layoutParams.resolveLayoutDirection(View.LAYOUT_DIRECTION_RTL); qtLayout.addView(webSlidingDrawer, layoutParams); webSlidingDrawer.setVisibility(View.GONE); + + headsetStateReceiver = new HeadsetStateReceiver(); } @Override @@ -161,6 +166,7 @@ public class InterfaceActivity extends QtActivity implements WebViewFragment.OnW } else { nativeEnterBackground(); } + unregisterReceiver(headsetStateReceiver); //gvrApi.pauseTracking(); } @@ -183,6 +189,7 @@ public class InterfaceActivity extends QtActivity implements WebViewFragment.OnW nativeEnterForeground(); surfacesWorkaround(); keepInterfaceRunning = false; + registerReceiver(headsetStateReceiver, new IntentFilter(Intent.ACTION_HEADSET_PLUG)); //gvrApi.resumeTracking(); } diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/MainActivity.java b/android/app/src/main/java/io/highfidelity/hifiinterface/MainActivity.java index db6f0fca24..4c6d05a3e8 100644 --- a/android/app/src/main/java/io/highfidelity/hifiinterface/MainActivity.java +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/MainActivity.java @@ -33,6 +33,7 @@ import io.highfidelity.hifiinterface.fragment.FriendsFragment; import io.highfidelity.hifiinterface.fragment.HomeFragment; import io.highfidelity.hifiinterface.fragment.LoginFragment; import io.highfidelity.hifiinterface.fragment.PolicyFragment; +import io.highfidelity.hifiinterface.fragment.SettingsFragment; import io.highfidelity.hifiinterface.task.DownloadProfileImageTask; public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, @@ -80,6 +81,8 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On mPeopleMenuItem = mNavigationView.getMenu().findItem(R.id.action_people); + updateDebugMenu(mNavigationView.getMenu()); + Toolbar toolbar = findViewById(R.id.toolbar); toolbar.setTitleTextAppearance(this, R.style.HomeActionBarTitleStyle); setSupportActionBar(toolbar); @@ -108,6 +111,16 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On } } + private void updateDebugMenu(Menu menu) { + if (BuildConfig.DEBUG) { + for (int i=0; i < menu.size(); i++) { + if (menu.getItem(i).getItemId() == R.id.action_debug_settings) { + menu.getItem(i).setVisible(true); + } + } + } + } + private void loadFragment(String fragment) { switch (fragment) { case "Login": @@ -151,6 +164,13 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On loadFragment(fragment, getString(R.string.people), getString(R.string.tagFragmentPeople), true); } + private void loadSettingsFragment() { + SettingsFragment fragment = SettingsFragment.newInstance(); + + loadFragment(fragment, getString(R.string.settings), getString(R.string.tagSettings), true); + } + + private void loadFragment(Fragment fragment, String title, String tag, boolean addToBackStack) { FragmentManager fragmentManager = getFragmentManager(); @@ -241,6 +261,9 @@ public class MainActivity extends AppCompatActivity implements NavigationView.On case R.id.action_people: loadPeopleFragment(); return true; + case R.id.action_debug_settings: + loadSettingsFragment(); + return true; } return false; } diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/SettingsFragment.java b/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/SettingsFragment.java new file mode 100644 index 0000000000..cc23665e72 --- /dev/null +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/fragment/SettingsFragment.java @@ -0,0 +1,63 @@ +package io.highfidelity.hifiinterface.fragment; + +import android.content.SharedPreferences; +import android.media.audiofx.AcousticEchoCanceler; +import android.os.Bundle; +import android.preference.Preference; +import android.preference.PreferenceFragment; +import android.support.annotation.Nullable; + +import io.highfidelity.hifiinterface.R; + +public class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener { + + public native void updateHifiSetting(String group, String key, boolean value); + public native boolean getHifiSettingBoolean(String group, String key, boolean defaultValue); + + private final String HIFI_SETTINGS_ANDROID_GROUP = "Android"; + private final String HIFI_SETTINGS_AEC_KEY = "aec"; + private final String PREFERENCE_KEY_AEC = "aec"; + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + addPreferencesFromResource(R.xml.settings); + + if (!AcousticEchoCanceler.isAvailable()) { + getPreferenceScreen().getPreferenceManager().findPreference("aec").setEnabled(false); + } + + getPreferenceScreen().getSharedPreferences().edit().putBoolean(PREFERENCE_KEY_AEC, + getHifiSettingBoolean(HIFI_SETTINGS_ANDROID_GROUP, HIFI_SETTINGS_AEC_KEY, false)); + } + + public static SettingsFragment newInstance() { + SettingsFragment fragment = new SettingsFragment(); + return fragment; + } + + @Override + public void onResume() { + super.onResume(); + getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this); + } + + @Override + public void onPause() { + super.onPause(); + getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this); + + } + + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + Preference pref = findPreference(key); + switch (key) { + case "aec": + updateHifiSetting(HIFI_SETTINGS_ANDROID_GROUP, HIFI_SETTINGS_AEC_KEY, sharedPreferences.getBoolean(key, false)); + break; + default: + break; + } + } +} diff --git a/android/app/src/main/java/io/highfidelity/hifiinterface/receiver/HeadsetStateReceiver.java b/android/app/src/main/java/io/highfidelity/hifiinterface/receiver/HeadsetStateReceiver.java new file mode 100644 index 0000000000..29bc1c49f2 --- /dev/null +++ b/android/app/src/main/java/io/highfidelity/hifiinterface/receiver/HeadsetStateReceiver.java @@ -0,0 +1,20 @@ +package io.highfidelity.hifiinterface.receiver; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.media.AudioManager; +import android.util.Log; + +public class HeadsetStateReceiver extends BroadcastReceiver { + + private native void notifyHeadsetOn(boolean pluggedIn); + + @Override + public void onReceive(Context context, Intent intent) { + AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); + + Log.d("[HEADSET] " , "BR - Wired headset on:" + audioManager.isWiredHeadsetOn()); + notifyHeadsetOn(audioManager.isWiredHeadsetOn()); + } +} diff --git a/android/app/src/main/res/menu/menu_navigation.xml b/android/app/src/main/res/menu/menu_navigation.xml index 3cce64f9f5..142af5d146 100644 --- a/android/app/src/main/res/menu/menu_navigation.xml +++ b/android/app/src/main/res/menu/menu_navigation.xml @@ -9,4 +9,9 @@ android:id="@+id/action_people" android:title="@string/people" /> + diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index b158aba59d..abde15f484 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -29,4 +29,9 @@ tagFragmentLogin tagFragmentPolicy tagFragmentPeople + tagSettings + Settings + AEC + Acoustic Echo Cancellation + Developer diff --git a/android/app/src/main/res/xml/settings.xml b/android/app/src/main/res/xml/settings.xml new file mode 100644 index 0000000000..5ec47b1aff --- /dev/null +++ b/android/app/src/main/res/xml/settings.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/interface/src/AndroidHelper.cpp b/interface/src/AndroidHelper.cpp index 419382f2cb..35bf094591 100644 --- a/interface/src/AndroidHelper.cpp +++ b/interface/src/AndroidHelper.cpp @@ -10,6 +10,7 @@ // #include "AndroidHelper.h" #include +#include #include "Application.h" #if defined(qApp) @@ -18,6 +19,7 @@ #define qApp (static_cast(QCoreApplication::instance())) AndroidHelper::AndroidHelper() { + qRegisterMetaType("QAudio::Mode"); } AndroidHelper::~AndroidHelper() { @@ -56,3 +58,18 @@ void AndroidHelper::processURL(const QString &url) { qApp->acceptURL(url); } } + +void AndroidHelper::notifyHeadsetOn(bool pluggedIn) { +#if defined (Q_OS_ANDROID) + auto audioClient = DependencyManager::get(); + if (audioClient) { + QAudioDeviceInfo activeDev = audioClient->getActiveAudioDevice(QAudio::AudioInput); + Setting::Handle enableAEC(QStringList() << ANDROID_SETTINGS_GROUP << SETTING_AEC_KEY, false); + if ((pluggedIn || !enableAEC.get()) && !activeDev.isNull() && activeDev.deviceName() != VOICE_RECOGNITION) { + QMetaObject::invokeMethod(audioClient.get(), "switchAudioDevice", Q_ARG(QAudio::Mode, QAudio::AudioInput), Q_ARG(QString, VOICE_RECOGNITION)); + } else if ( (!pluggedIn && enableAEC.get()) && !activeDev.isNull() && activeDev.deviceName() != VOICE_COMMUNICATION) { + QMetaObject::invokeMethod(audioClient.get(), "switchAudioDevice", Q_ARG(QAudio::Mode, QAudio::AudioInput), Q_ARG(QString, VOICE_COMMUNICATION)); + } + } +#endif +} diff --git a/interface/src/AndroidHelper.h b/interface/src/AndroidHelper.h index 03d92f91d9..11b84e4025 100644 --- a/interface/src/AndroidHelper.h +++ b/interface/src/AndroidHelper.h @@ -29,6 +29,7 @@ public: void performHapticFeedback(int duration); void processURL(const QString &url); + void notifyHeadsetOn(bool pluggedIn); AndroidHelper(AndroidHelper const&) = delete; void operator=(AndroidHelper const&) = delete; diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 6a9363f309..e23b8ac3cd 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -53,7 +53,6 @@ #include "AudioHelpers.h" #if defined(Q_OS_ANDROID) -#define VOICE_RECOGNITION "voicerecognition" #include #endif @@ -451,9 +450,12 @@ QAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { #if defined (Q_OS_ANDROID) if (mode == QAudio::AudioInput) { + Setting::Handle enableAEC(QStringList() << ANDROID_SETTINGS_GROUP << SETTING_AEC_KEY, false); + bool aecEnabled = enableAEC.get(); auto inputDevices = QAudioDeviceInfo::availableDevices(QAudio::AudioInput); for (auto inputDevice : inputDevices) { - if (inputDevice.deviceName() == VOICE_RECOGNITION) { + if ((aecEnabled && inputDevice.deviceName() == VOICE_COMMUNICATION) || + (!aecEnabled && inputDevice.deviceName() == VOICE_RECOGNITION)) { return inputDevice; } } diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index 8599c990a3..fa7ac40a16 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -64,6 +64,14 @@ #pragma warning( pop ) #endif +#if defined (Q_OS_ANDROID) +#define VOICE_RECOGNITION "voicerecognition" +#define VOICE_COMMUNICATION "voicecommunication" + +#define ANDROID_SETTINGS_GROUP "Android" +#define SETTING_AEC_KEY "aec" +#endif + class QAudioInput; class QAudioOutput; class QIODevice; From 38bfee7b723704a3a92d988b389b923b87c173ef Mon Sep 17 00:00:00 2001 From: sam gateau Date: Thu, 6 Sep 2018 13:54:21 -0700 Subject: [PATCH 321/545] Fix compilation on android and add the simple getBufferIDUnsynced in bindUniformBuffer --- .../gpu-gl-common/src/gpu/gl/GLBackend.h | 2 +- .../src/gpu/gl/GLBackendInput.cpp | 22 +++++-------------- .../src/gpu/gl/GLBackendPipeline.cpp | 13 +++++------ libraries/gpu-gl-common/src/gpu/gl/GLBuffer.h | 6 ++--- libraries/gpu-gl/src/gpu/gl41/GL41Backend.h | 2 +- .../gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp | 4 ++-- libraries/gpu-gl/src/gpu/gl45/GL45Backend.h | 2 +- .../gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp | 5 ++--- libraries/gpu-gles/src/gpu/gles/GLESBackend.h | 1 + .../src/gpu/gles/GLESBackendBuffer.cpp | 4 ++++ 10 files changed, 25 insertions(+), 36 deletions(-) diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h index 2fa2df5bfa..9b3a28e6fd 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackend.h @@ -239,7 +239,7 @@ public: virtual GLuint getFramebufferID(const FramebufferPointer& framebuffer) = 0; virtual GLuint getTextureID(const TexturePointer& texture) final; virtual GLuint getBufferID(const Buffer& buffer) = 0; - virtual GLuint getBufferIDUnsafe(const Buffer& buffer) = 0; + virtual GLuint getBufferIDUnsynced(const Buffer& buffer) = 0; virtual GLuint getQueryID(const QueryPointer& query) = 0; virtual GLFramebuffer* syncGPUObject(const Framebuffer& framebuffer) = 0; diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp index 9fe1aa4029..f326ef39b9 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp @@ -40,23 +40,11 @@ void GLBackend::do_setInputBuffer(const Batch& batch, size_t paramOffset) { BufferPointer buffer = batch._buffers.get(batch._params[paramOffset + 2]._uint); uint32 channel = batch._params[paramOffset + 3]._uint; - // if (channel < getNumInputBuffers()) { + if (channel < getNumInputBuffers()) { bool isModified = false; if (_input._buffers[channel] != buffer) { _input._buffers[channel] = buffer; - - GLuint vbo = 0; - if (buffer) { - // vbo = getBufferID((*buffer)); - // vbo = getBufferIDUnsafe((*buffer)); - auto* object = Backend::getGPUObject((*buffer)); - - if (object) { - vbo = object->_buffer; - } - } - _input._bufferVBOs[channel] = vbo; - + _input._bufferVBOs[channel] = getBufferIDUnsynced((*buffer)); isModified = true; } @@ -73,7 +61,7 @@ void GLBackend::do_setInputBuffer(const Batch& batch, size_t paramOffset) { if (isModified) { _input._invalidBuffers.set(channel); } - // } + } } void GLBackend::initInput() { @@ -135,7 +123,7 @@ void GLBackend::do_setIndexBuffer(const Batch& batch, size_t paramOffset) { if (indexBuffer != _input._indexBuffer) { _input._indexBuffer = indexBuffer; if (indexBuffer) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, getBufferIDUnsafe(*indexBuffer)); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, getBufferIDUnsynced(*indexBuffer)); } else { // FIXME do we really need this? Is there ever a draw call where we care that the element buffer is null? glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); @@ -152,7 +140,7 @@ void GLBackend::do_setIndirectBuffer(const Batch& batch, size_t paramOffset) { if (buffer != _input._indirectBuffer) { _input._indirectBuffer = buffer; if (buffer) { - glBindBuffer(GL_DRAW_INDIRECT_BUFFER, getBufferIDUnsafe(*buffer)); + glBindBuffer(GL_DRAW_INDIRECT_BUFFER, getBufferIDUnsynced(*buffer)); } else { // FIXME do we really need this? Is there ever a draw call where we care that the element buffer is null? glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0); diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackendPipeline.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendPipeline.cpp index fd67202863..05ded3eece 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackendPipeline.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackendPipeline.cpp @@ -85,6 +85,8 @@ void GLBackend::do_setPipeline(const Batch& batch, size_t paramOffset) { auto& cameraCorrectionBuffer = _transform._viewCorrectionEnabled ? _pipeline._cameraCorrectionBuffer._buffer : _pipeline._cameraCorrectionBufferIdentity._buffer; + // Because we don't sync Buffers in the bindUniformBuffer, let s force this buffer synced + getBufferID(*cameraCorrectionBuffer); bindUniformBuffer(gpu::slot::buffer::CameraCorrection, cameraCorrectionBuffer, 0, sizeof(CameraCorrection)); } (void)CHECK_GL_ERROR(); @@ -170,13 +172,10 @@ void GLBackend::bindUniformBuffer(uint32_t slot, const BufferPointer& buffer, GL return; } - // Sync BufferObject - auto* object = syncGPUObject(*bufferState.buffer); - // auto glBO = getBufferIDUnsafe(*buffer); - - if (object) { - glBindBufferRange(GL_UNIFORM_BUFFER, slot, object->_buffer, bufferState.offset, bufferState.size); - + // Grab the true gl Buffer object + auto glBO = getBufferIDUnsynced(*buffer); + if (glBO) { + glBindBufferRange(GL_UNIFORM_BUFFER, slot, glBO, bufferState.offset, bufferState.size); _uniform._buffers[slot] = bufferState; (void)CHECK_GL_ERROR(); } else { diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBuffer.h b/libraries/gpu-gl-common/src/gpu/gl/GLBuffer.h index 8efbe03b90..b9fe125c8d 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBuffer.h +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBuffer.h @@ -50,13 +50,11 @@ public: } template - static GLuint getIdUnsafe(GLBackend& backend, const Buffer& buffer) { + static GLuint getIdUnsynced(GLBackend& backend, const Buffer& buffer) { GLBufferType* object = Backend::getGPUObject(buffer); - if (object) { return object->_buffer; - } - else { + } else { return 0; } } diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h b/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h index a09b3e9297..f4078f5479 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h +++ b/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h @@ -134,7 +134,7 @@ protected: GLFramebuffer* syncGPUObject(const Framebuffer& framebuffer) override; GLuint getBufferID(const Buffer& buffer) override; - GLuint getBufferIDUnsafe(const Buffer& buffer) override; + GLuint getBufferIDUnsynced(const Buffer& buffer) override; GLuint getResourceBufferID(const Buffer& buffer); GLBuffer* syncGPUObject(const Buffer& buffer) override; diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp index 97ac2739eb..ac5d5ee0c9 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp @@ -83,8 +83,8 @@ GLuint GL41Backend::getBufferID(const Buffer& buffer) { return GL41Buffer::getId(*this, buffer); } -GLuint GL41Backend::getBufferIDUnsafe(const Buffer& buffer) { - return GL41Backend::getBufferID(buffer); +GLuint GL41Backend::getBufferIDUnsynced(const Buffer& buffer) { + return GL41Buffer::getIdUnsynced(*this, buffer); } GLuint GL41Backend::getResourceBufferID(const Buffer& buffer) { diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h index 5da4506773..a100faf432 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h +++ b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h @@ -235,7 +235,7 @@ protected: GLFramebuffer* syncGPUObject(const Framebuffer& framebuffer) override; GLuint getBufferID(const Buffer& buffer) override; - GLuint getBufferIDUnsafe(const Buffer& buffer) override; + GLuint getBufferIDUnsynced(const Buffer& buffer) override; GLBuffer* syncGPUObject(const Buffer& buffer) override; GLTexture* syncGPUObject(const TexturePointer& texture) override; diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp index 0d26f8f412..6d17923ebd 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp @@ -51,9 +51,8 @@ GLuint GL45Backend::getBufferID(const Buffer& buffer) { return GL45Buffer::getId(*this, buffer); } -GLuint GL45Backend::getBufferIDUnsafe(const Buffer& buffer) { - //return GL45Buffer::getId(*this, buffer); - return GL45Buffer::getIdUnsafe(*this, buffer); +GLuint GL45Backend::getBufferIDUnsynced(const Buffer& buffer) { + return GL45Buffer::getIdUnsynced(*this, buffer); } GLBuffer* GL45Backend::syncGPUObject(const Buffer& buffer) { diff --git a/libraries/gpu-gles/src/gpu/gles/GLESBackend.h b/libraries/gpu-gles/src/gpu/gles/GLESBackend.h index 785f4c3ef9..c757de0a72 100644 --- a/libraries/gpu-gles/src/gpu/gles/GLESBackend.h +++ b/libraries/gpu-gles/src/gpu/gles/GLESBackend.h @@ -130,6 +130,7 @@ protected: GLFramebuffer* syncGPUObject(const Framebuffer& framebuffer) override; GLuint getBufferID(const Buffer& buffer) override; + GLuint getBufferIDUnsynced(const Buffer& buffer) override; GLuint getResourceBufferID(const Buffer& buffer); GLBuffer* syncGPUObject(const Buffer& buffer) override; diff --git a/libraries/gpu-gles/src/gpu/gles/GLESBackendBuffer.cpp b/libraries/gpu-gles/src/gpu/gles/GLESBackendBuffer.cpp index 17fdad8377..7dd08df409 100644 --- a/libraries/gpu-gles/src/gpu/gles/GLESBackendBuffer.cpp +++ b/libraries/gpu-gles/src/gpu/gles/GLESBackendBuffer.cpp @@ -64,6 +64,10 @@ GLuint GLESBackend::getBufferID(const Buffer& buffer) { return GLESBuffer::getId(*this, buffer); } +GLuint GLESBackend::getBufferIDUnsynced(const Buffer& buffer) { + return GLESBuffer::getIdUnsynced(*this, buffer); +} + GLBuffer* GLESBackend::syncGPUObject(const Buffer& buffer) { return GLESBuffer::sync(*this, buffer); } From 6544e9f0b004cb9c6b43da5405e2f2f1c98fbd46 Mon Sep 17 00:00:00 2001 From: sam gateau Date: Thu, 6 Sep 2018 13:58:03 -0700 Subject: [PATCH 322/545] Removing the commented debug code --- libraries/fbx/src/FBXReader_Mesh.cpp | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index 7b83e74ebc..19bd99ec5d 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -781,20 +781,7 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { attribChannel = 2; totalAttribBufferSize = totalVertsSize - positionsSize - normalsAndTangentsSize; - } /*else { - auto posBuffer = std::make_shared(); - posBuffer->setData(positionsSize, (const gpu::Byte*) vertBuffer->getData() + positionsOffset); - vertexBufferStream->addBuffer(posBuffer, 0, positionElement.getSize()); - - // update channels and attribBuffer size accordingly - interleavePositions = false; - interleaveNormalsTangents = true; - - tangentChannel = 1; - attribChannel = 1; - - totalAttribBufferSize = totalVertsSize - positionsSize; - }*/ + } // Define the vertex format, compute the offset for each attributes as we append them to the vertex format gpu::Offset bufOffset = 0; From 00e10ad684f5823e571c16e9e5e4f536877341ff Mon Sep 17 00:00:00 2001 From: Alexia Mandeville Date: Thu, 6 Sep 2018 14:05:51 -0700 Subject: [PATCH 323/545] Updating sign up text, moving forgotten info links --- .../resources/qml/LoginDialog/LinkAccountBody.qml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index 423f6cc73b..783027761a 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -128,9 +128,8 @@ Item { ShortcutText { z: 10 anchors { - left: usernameField.right - top: usernameField.bottom - leftMargin: usernameField.textFieldLabel.contentWidth + 10 + right: usernameField.right + top: usernameField.top topMargin: -19 } @@ -157,9 +156,8 @@ Item { ShortcutText { z: 10 anchors { - left: passwordField.right - top: passwordField.bottom - leftMargin: passwordField.textFieldLabel.contentWidth + 10 + right: passwordField.right + top: passwordField.top topMargin: -19 } @@ -232,7 +230,7 @@ Item { RalewaySemiBold { size: hifi.fontSizes.inputLabel anchors.verticalCenter: parent.verticalCenter - text: qsTr("Don't have an account?") + text: qsTr("New to High Fidelity?") } Button { From aabfda6eb5a90072e7c2f84c8e032ed4f4322f9c Mon Sep 17 00:00:00 2001 From: Alexia Mandeville Date: Thu, 6 Sep 2018 14:16:42 -0700 Subject: [PATCH 324/545] Adding descriptive text --- .../qml/LoginDialog/LinkAccountBody.qml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index 783027761a..60c7a26e89 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -87,6 +87,22 @@ Item { height: 48 } + ShortcutText { + id: flavorText + anchors { + top: parent.top + left: parent.left + margins: 0 + topMargin: hifi.dimensions.contentSpacing.y + } + + text: qsTr("Sign in to High Fidelity to make friends, get HFC, and buy interesting things on the Marketplace!") + wrapMode: Text.WordWrap + lineHeight: 1 + lineHeightMode: Text.ProportionalHeight + horizontalAlignment: Text.AlignHCenter + } + ShortcutText { id: mainTextContainer anchors { From 98dafa3b67ca6e87432076c4b9c43778b31741fc Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Thu, 6 Sep 2018 14:31:49 -0700 Subject: [PATCH 325/545] fix overlayParentID --- scripts/system/interstitialPage.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/system/interstitialPage.js b/scripts/system/interstitialPage.js index c56e16d429..c95845656c 100644 --- a/scripts/system/interstitialPage.js +++ b/scripts/system/interstitialPage.js @@ -419,6 +419,10 @@ }); MyAvatar.sensorToWorldScaleChanged.connect(scaleInterstitialPage); + MyAvatar.sessionUUIDChanged.connect(function() { + var avatarSessionUUID = MyAvatar.sessionUUID; + Overlays.editOverlay(loadingSphereID, { parentID: avatarSessionUUID }); + }); var toggle = true; if (DEBUG) { From 021146e4f0d6911d9c9ca57e88719932730c002a Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 6 Sep 2018 15:33:52 -0700 Subject: [PATCH 326/545] minor tweak to default avatar-update sort coefficients --- libraries/avatars/src/AvatarData.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 6896883f74..13adc803dd 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -2822,7 +2822,7 @@ void RayToAvatarIntersectionResultFromScriptValue(const QScriptValue& object, Ra const float AvatarData::OUT_OF_VIEW_PENALTY = -10.0f; -float AvatarData::_avatarSortCoefficientSize { 4.0f }; +float AvatarData::_avatarSortCoefficientSize { 8.0f }; float AvatarData::_avatarSortCoefficientCenter { 4.0f }; float AvatarData::_avatarSortCoefficientAge { 1.0f }; From 229e9624e62f2afe29b55cccef4fdf2fc4d7eb7c Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 6 Sep 2018 15:34:28 -0700 Subject: [PATCH 327/545] remove bad bounding box calculations in avatar-mixer --- .../src/avatars/AvatarMixerClientData.h | 1 + .../src/avatars/AvatarMixerSlave.cpp | 43 +++++++------------ 2 files changed, 17 insertions(+), 27 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixerClientData.h b/assignment-client/src/avatars/AvatarMixerClientData.h index ee27f9bb0f..81a4a58769 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.h +++ b/assignment-client/src/avatars/AvatarMixerClientData.h @@ -45,6 +45,7 @@ public: int parseData(ReceivedMessage& message) override; AvatarData& getAvatar() { return *_avatar; } + const AvatarData& getAvatar() const { return *_avatar; } const AvatarData* getConstAvatarData() const { return _avatar.get(); } AvatarSharedPointer getAvatarSharedPointer() const { return _avatar; } diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index a61f65ffb0..3e83a78341 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -212,6 +212,15 @@ void AvatarMixerSlave::broadcastAvatarData(const SharedNodePointer& node) { _stats.jobElapsedTime += (end - start); } +AABox computeBubbleBox(const AvatarData& avatar, float bubbleExpansionFactor) { + glm::vec3 position = avatar.getClientGlobalPosition(); + glm::vec3 scale = 2.0f * (avatar.getClientGlobalPosition()- avatar.getGlobalBoundingBoxCorner()); + scale *= bubbleExpansionFactor; + const glm::vec3 MIN_BUBBLE_SCALE(0.3f, 1.3f, 0.3); + scale = glm::max(scale, MIN_BUBBLE_SCALE); + return AABox(position - 0.5f * scale, scale); +} + void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) { const Node* destinationNode = node.data(); @@ -275,18 +284,9 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // setup a PacketList for the avatarPackets auto avatarPacketList = NLPacketList::create(PacketType::BulkAvatarData); - // Define the minimum bubble size - const glm::vec3 minBubbleSize = avatar.getSensorToWorldScale() * glm::vec3(0.3f, 1.3f, 0.3f); - // Define the scale of the box for the current node - glm::vec3 nodeBoxScale = (avatar.getClientGlobalPosition() - avatar.getGlobalBoundingBoxCorner()) * 2.0f * avatar.getSensorToWorldScale(); - // Set up the bounding box for the current node - AABox nodeBox(avatar.getGlobalBoundingBoxCorner(), nodeBoxScale); - // Clamp the size of the bounding box to a minimum scale - if (glm::any(glm::lessThan(nodeBoxScale, minBubbleSize))) { - nodeBox.setScaleStayCentered(minBubbleSize); - } - // Quadruple the scale of first bounding box - nodeBox.embiggen(4.0f); + // compute node bounding box + const float MY_AVATAR_BUBBLE_EXPANSION_FACTOR = 4.0f; // magic number determined emperically + AABox nodeBox = computeBubbleBox(avatar, MY_AVATAR_BUBBLE_EXPANSION_FACTOR ); class SortableAvatar: public PrioritySortUtil::Sortable { public: @@ -295,7 +295,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) : _avatar(avatar), _node(avatarNode), _lastEncodeTime(lastEncodeTime) {} glm::vec3 getPosition() const override { return _avatar->getClientGlobalPosition(); } float getRadius() const override { - glm::vec3 nodeBoxHalfScale = (_avatar->getClientGlobalPosition() - _avatar->getGlobalBoundingBoxCorner() * _avatar->getSensorToWorldScale()); + glm::vec3 nodeBoxHalfScale = _avatar->getClientGlobalPosition() - _avatar->getGlobalBoundingBoxCorner(); return glm::max(nodeBoxHalfScale.x, glm::max(nodeBoxHalfScale.y, nodeBoxHalfScale.z)); } uint64_t getTimestamp() const override { @@ -351,20 +351,9 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // Check to see if the space bubble is enabled // Don't bother with these checks if the other avatar has their bubble enabled and we're gettingAnyIgnored if (destinationNode->isIgnoreRadiusEnabled() || (avatarNode->isIgnoreRadiusEnabled() && !getsAnyIgnored)) { - float sensorToWorldScale = avatarClientNodeData->getAvatarSharedPointer()->getSensorToWorldScale(); - // Define the scale of the box for the current other node - glm::vec3 otherNodeBoxScale = (avatarClientNodeData->getPosition() - avatarClientNodeData->getGlobalBoundingBoxCorner()) * 2.0f * sensorToWorldScale; - // Set up the bounding box for the current other node - AABox otherNodeBox(avatarClientNodeData->getGlobalBoundingBoxCorner(), otherNodeBoxScale); - // Clamp the size of the bounding box to a minimum scale - if (glm::any(glm::lessThan(otherNodeBoxScale, minBubbleSize))) { - otherNodeBox.setScaleStayCentered(minBubbleSize); - } - // Change the scale of other bounding box - // (This is an arbitrary number determined empirically) - otherNodeBox.embiggen(2.4f); - // Perform the collision check between the two bounding boxes + const float OTHER_AVATAR_BUBBLE_EXPANSION_FACTOR = 2.4f; // magic number determined empirically + AABox otherNodeBox = computeBubbleBox(avatarClientNodeData->getAvatar(), OTHER_AVATAR_BUBBLE_EXPANSION_FACTOR); if (nodeBox.touches(otherNodeBox)) { nodeData->ignoreOther(destinationNode, avatarNode); shouldIgnore = !getsAnyIgnored; @@ -445,7 +434,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // determine if avatar is in view which determines how much data to send glm::vec3 otherPosition = otherAvatar->getClientGlobalPosition(); - glm::vec3 otherNodeBoxScale = (otherPosition - otherNodeData->getGlobalBoundingBoxCorner()) * 2.0f * otherAvatar->getSensorToWorldScale(); + glm::vec3 otherNodeBoxScale = otherPosition - otherNodeData->getGlobalBoundingBoxCorner(); AABox otherNodeBox(otherNodeData->getGlobalBoundingBoxCorner(), otherNodeBoxScale); bool isInView = nodeData->otherAvatarInView(otherNodeBox); From 0e785f9bdb0746888209a8826bd48a1fb6915198 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 6 Sep 2018 15:35:26 -0700 Subject: [PATCH 328/545] Fix MS17877: Persist Connections table sort choice --- interface/resources/qml/hifi/Pal.qml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/interface/resources/qml/hifi/Pal.qml b/interface/resources/qml/hifi/Pal.qml index cbab83ea28..35a0078d32 100644 --- a/interface/resources/qml/hifi/Pal.qml +++ b/interface/resources/qml/hifi/Pal.qml @@ -780,6 +780,12 @@ Rectangle { headerVisible: true; sortIndicatorColumn: settings.connectionsSortIndicatorColumn; sortIndicatorOrder: settings.connectionsSortIndicatorOrder; + onSortIndicatorColumnChanged: { + settings.connectionsSortIndicatorColumn = sortIndicatorColumn; + } + onSortIndicatorOrderChanged: { + settings.connectionsSortIndicatorOrder = sortIndicatorOrder; + } TableViewColumn { id: connectionsUserNameHeader; From 734956211151b4ee4566732e743f5b86bc87dea1 Mon Sep 17 00:00:00 2001 From: sam gateau Date: Thu, 6 Sep 2018 15:50:31 -0700 Subject: [PATCH 329/545] Removing commented code --- libraries/gpu/src/gpu/Batch.h | 5 +---- libraries/graphics/src/graphics/Geometry.cpp | 2 -- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index 2bead507b8..bb38379a66 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -417,10 +417,7 @@ public: } const Data& get(uint32 offset) const { - /* if (offset >= _items.size()) { - static const Data EMPTY; - return EMPTY; - }*/ + assert((offset >= _items.size())); return (_items.data() + offset)->_data; } diff --git a/libraries/graphics/src/graphics/Geometry.cpp b/libraries/graphics/src/graphics/Geometry.cpp index 5a374ae8d0..a983ba07b4 100755 --- a/libraries/graphics/src/graphics/Geometry.cpp +++ b/libraries/graphics/src/graphics/Geometry.cpp @@ -119,7 +119,6 @@ Box Mesh::evalPartBound(int partNum) const { for (;index != endIndex; index++) { // skip primitive restart indices if ((*index) != PRIMITIVE_RESTART_INDEX) { - // box += vertices[(*index)]; box += _vertexBuffer.get(part._baseVertex + (*index)); } } @@ -140,7 +139,6 @@ Box Mesh::evalPartsBound(int partStart, int partEnd) const { for (;index != endIndex; index++) { // skip primitive restart indices if ((*index) != (uint) PRIMITIVE_RESTART_INDEX) { - //partBound += vertices[(*index)]; partBound += _vertexBuffer.get((*part)._baseVertex + (*index)); } } From a908c1554f4d1a35d88577cfaf47b09d2948645f Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 6 Sep 2018 16:04:54 -0700 Subject: [PATCH 330/545] make sure ignoredNode is available before sending packet --- assignment-client/src/avatars/AvatarMixer.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 0289a8aa3f..561afee296 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -655,11 +655,14 @@ void AvatarMixer::handleNodeIgnoreRequestPacket(QSharedPointer if (addToIgnore) { senderNode->addIgnoredNode(ignoredUUID); - // send a reliable kill packet to remove the sending avatar for the ignored avatar - auto killPacket = NLPacket::create(PacketType::KillAvatar, NUM_BYTES_RFC4122_UUID + sizeof(KillAvatarReason), true); - killPacket->write(senderNode->getUUID().toRfc4122()); - killPacket->writePrimitive(KillAvatarReason::AvatarDisconnected); - nodeList->sendPacket(std::move(killPacket), *ignoredNode); + if (ignoredNode) { + // send a reliable kill packet to remove the sending avatar for the ignored avatar + auto killPacket = NLPacket::create(PacketType::KillAvatar, + NUM_BYTES_RFC4122_UUID + sizeof(KillAvatarReason), true); + killPacket->write(senderNode->getUUID().toRfc4122()); + killPacket->writePrimitive(KillAvatarReason::AvatarDisconnected); + nodeList->sendPacket(std::move(killPacket), *ignoredNode); + } } else { senderNode->removeIgnoredNode(ignoredUUID); } From 3d75d4726af0ce63318d1a40ac500374c1260c5d Mon Sep 17 00:00:00 2001 From: David Back Date: Thu, 6 Sep 2018 16:04:59 -0700 Subject: [PATCH 331/545] scale invertly once passing minimum --- .../system/libraries/entitySelectionTool.js | 28 +++++-------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index 945f6a88d7..5b82b7d38b 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -2283,39 +2283,25 @@ SelectionDisplay = (function() { var changeInDimensions = Vec3.multiply(NEGATE_VECTOR, vec3Mult(localSigns, vector)); + var newDimensions; if (proportional) { var viewportDimensions = Controller.getViewportDimensions(); var mouseXDifference = (event.x - beginMouseEvent.x) / viewportDimensions.x; var mouseYDifference = (beginMouseEvent.y - event.y) / viewportDimensions.y; var mouseDifference = mouseXDifference + mouseYDifference; - changeInDimensions = { x:mouseDifference, y:mouseDifference, z:mouseDifference }; var toCameraDistance = getDistanceToCamera(position); var dimensionsMultiple = toCameraDistance * STRETCH_DIRECTION_ALL_CAMERA_DISTANCE_MULTIPLE; - changeInDimensions = Vec3.multiply(changeInDimensions, dimensionsMultiple); - } - - var newDimensions; - if (proportional) { - var absoluteX = Math.abs(changeInDimensions.x); - var absoluteY = Math.abs(changeInDimensions.y); - var absoluteZ = Math.abs(changeInDimensions.z); - var percentChange = 0; - if (absoluteX > absoluteY && absoluteX > absoluteZ) { - percentChange = changeInDimensions.x / initialProperties.dimensions.x; - percentChange = changeInDimensions.x / initialDimensions.x; - } else if (absoluteY > absoluteZ) { - percentChange = changeInDimensions.y / initialProperties.dimensions.y; - percentChange = changeInDimensions.y / initialDimensions.y; - } else { - percentChange = changeInDimensions.z / initialProperties.dimensions.z; - percentChange = changeInDimensions.z / initialDimensions.z; - } + var dimensionChange = mouseDifference * dimensionsMultiple; + percentChange = dimensionChange / initialDimensions.z; percentChange += 1.0; newDimensions = Vec3.multiply(percentChange, initialDimensions); + newDimensions.x = Math.abs(newDimensions.x); + newDimensions.y = Math.abs(newDimensions.y); + newDimensions.z = Math.abs(newDimensions.z); } else { newDimensions = Vec3.sum(initialDimensions, changeInDimensions); } - + var minimumDimension = directionEnum === STRETCH_DIRECTION.ALL ? STRETCH_ALL_MINIMUM_DIMENSION : STRETCH_MINIMUM_DIMENSION; if (newDimensions.x < minimumDimension) { From 8e5f5cc7965a8a59eab894451ec2a54d5174a568 Mon Sep 17 00:00:00 2001 From: Alexia Mandeville Date: Thu, 6 Sep 2018 16:16:43 -0700 Subject: [PATCH 332/545] Moving forgotten links --- interface/resources/qml/LoginDialog/LinkAccountBody.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index 60c7a26e89..d2a97874b1 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -145,7 +145,7 @@ Item { z: 10 anchors { right: usernameField.right - top: usernameField.top + top: usernameField.bottom topMargin: -19 } @@ -173,7 +173,7 @@ Item { z: 10 anchors { right: passwordField.right - top: passwordField.top + top: passwordField.bottom topMargin: -19 } From acc7f1f168b734e0d58341a241174ee06b1fcd44 Mon Sep 17 00:00:00 2001 From: Anthony Thibault Date: Thu, 6 Sep 2018 16:18:01 -0700 Subject: [PATCH 333/545] Moved AnimStats into its own qml panels. Added state machine tracking as well. --- interface/resources/qml/AnimStats.qml | 157 +++++++++++++++++++ interface/resources/qml/Stats.qml | 35 ++++- interface/src/Application.cpp | 4 + interface/src/Menu.cpp | 1 + interface/src/Menu.h | 1 + interface/src/ui/AnimStats.cpp | 141 +++++++++++++++++ interface/src/ui/AnimStats.h | 55 +++++++ interface/src/ui/Stats.cpp | 12 +- interface/src/ui/Stats.h | 12 +- libraries/animation/src/AnimContext.h | 14 ++ libraries/animation/src/AnimStateMachine.cpp | 5 +- libraries/animation/src/AnimStateMachine.h | 1 + libraries/animation/src/Rig.h | 1 + 13 files changed, 427 insertions(+), 12 deletions(-) create mode 100644 interface/resources/qml/AnimStats.qml create mode 100644 interface/src/ui/AnimStats.cpp create mode 100644 interface/src/ui/AnimStats.h diff --git a/interface/resources/qml/AnimStats.qml b/interface/resources/qml/AnimStats.qml new file mode 100644 index 0000000000..35ed3799a6 --- /dev/null +++ b/interface/resources/qml/AnimStats.qml @@ -0,0 +1,157 @@ +import Hifi 1.0 as Hifi +import QtQuick 2.3 +import '.' + +Item { + id: animStats + + anchors.leftMargin: 300 + objectName: "StatsItem" + property int modality: Qt.NonModal + implicitHeight: row.height + implicitWidth: row.width + + Component.onCompleted: { + animStats.parentChanged.connect(fill); + fill(); + } + Component.onDestruction: { + animStats.parentChanged.disconnect(fill); + } + + function fill() { + // This will cause a warning at shutdown, need to find another way to remove + // the warning other than filling the anchors to the parent + anchors.horizontalCenter = parent.horizontalCenter + } + + Hifi.AnimStats { + id: root + objectName: "AnimStats" + implicitHeight: row.height + implicitWidth: row.width + + anchors.horizontalCenter: parent.horizontalCenter + readonly property string bgColor: "#AA111111" + + Row { + id: row + spacing: 8 + + Rectangle { + width: firstCol.width + 8; + height: firstCol.height + 8; + color: root.bgColor; + + Column { + id: firstCol + spacing: 4; x: 4; y: 4; + + StatText { + text: "State Machines:---------------------------------------------------------------------------" + } + ListView { + width: firstCol.width + height: root.animStateMachines.length * 15 + visible: root.animStateMchines.length > 0; + model: root.animStateMachines + delegate: StatText { + text: { + return modelData; + } + } + } + } + } + + Rectangle { + width: secondCol.width + 8 + height: secondCol.height + 8 + color: root.bgColor; + + Column { + id: secondCol + spacing: 4; x: 4; y: 4; + + StatText { + text: "Anim Vars:--------------------------------------------------------------------------------" + } + + ListView { + width: secondCol.width + height: root.animVars.length * 15 + visible: root.animVars.length > 0; + model: root.animVars + delegate: StatText { + text: { + var actualText = modelData.split("|")[1]; + if (actualText) { + return actualText; + } else { + return modelData; + } + } + color: { + var grayScale = parseFloat(modelData.split("|")[0]); + return Qt.rgba(1.0, 1.0, 1.0, grayScale); + } + styleColor: { + var grayScale = parseFloat(modelData.split("|")[0]); + return Qt.rgba(0.0, 0.0, 0.0, grayScale); + } + } + } + } + } + + Rectangle { + width: thirdCol.width + 8 + height: thirdCol.height + 8 + color: root.bgColor; + + Column { + id: thirdCol + spacing: 4; x: 4; y: 4; + + StatText { + text: "Alpha Values:--------------------------------------------------------------------------" + } + + ListView { + width: thirdCol.width + height: root.animAlphaValues.length * 15 + visible: root.animAlphaValues.length > 0; + model: root.animAlphaValues + delegate: StatText { + text: { + var actualText = modelData.split("|")[1]; + if (actualText) { + return actualText; + } else { + return modelData; + } + } + color: { + var grayScale = parseFloat(modelData.split("|")[0]); + return Qt.rgba(1.0, 1.0, 1.0, grayScale); + } + styleColor: { + var grayScale = parseFloat(modelData.split("|")[0]); + return Qt.rgba(0.0, 0.0, 0.0, grayScale); + } + } + } + + } + } + } + + Connections { + target: root.parent + onWidthChanged: { + root.x = root.parent.width - root.width; + } + } + } + +} diff --git a/interface/resources/qml/Stats.qml b/interface/resources/qml/Stats.qml index 26682d3db8..f74f0539c9 100644 --- a/interface/resources/qml/Stats.qml +++ b/interface/resources/qml/Stats.qml @@ -192,6 +192,25 @@ Item { StatText { text: "Yaw: " + root.yaw.toFixed(1) } + StatText { + visible: root.animStateMachines.length > 0; + text: "Anim State Machines:" + } + ListView { + width: geoCol.width + height: root.animStateMachines.length * 15 + visible: root.animStateMchines.length > 0; + model: root.animStateMachines + delegate: StatText { + text: { + if (modelData.length > 30) { + return modelData.substring(0, 5) + "..." + modelData.substring(.length - 22); + } else { + return modelData; + } + } + } + } StatText { visible: root.animAlphaValues.length > 0; text: "Anim Alpha Values:" @@ -216,9 +235,11 @@ Item { } color: { var grayScale = parseFloat(modelData.split("|")[0]); - return Qt.rgba(0.3 * grayScale + 0.7, - 0.3 * grayScale + 0.7, - 0.3 * grayScale + 0.7, 1.0); + return Qt.rgba(1.0, 1.0, 1.0, grayScale); + } + styleColor: { + var grayScale = parseFloat(modelData.split("|")[0]); + return Qt.rgba(0.0, 0.0, 0.0, grayScale); } } } @@ -246,9 +267,11 @@ Item { } color: { var grayScale = parseFloat(modelData.split("|")[0]); - return Qt.rgba(0.3 * grayScale + 0.7, - 0.3 * grayScale + 0.7, - 0.3 * grayScale + 0.7, 1.0); + return Qt.rgba(1.0, 1.0, 1.0, grayScale); + } + styleColor: { + var grayScale = parseFloat(modelData.split("|")[0]); + return Qt.rgba(0.0, 0.0, 0.0, grayScale); } } } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2fe67ec5cb..40edcdbd76 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -195,6 +195,7 @@ #include "ui/SnapshotAnimated.h" #include "ui/StandAloneJSConsole.h" #include "ui/Stats.h" +#include "ui/AnimStats.h" #include "ui/UpdateDialog.h" #include "ui/overlays/Overlays.h" #include "ui/DomainConnectionModel.h" @@ -3081,8 +3082,10 @@ void Application::onDesktopRootContextCreated(QQmlContext* surfaceContext) { void Application::onDesktopRootItemCreated(QQuickItem* rootItem) { Stats::show(); + AnimStats::show(); auto surfaceContext = DependencyManager::get()->getSurfaceContext(); surfaceContext->setContextProperty("Stats", Stats::getInstance()); + surfaceContext->setContextProperty("AnimStats", AnimStats::getInstance()); #if !defined(Q_OS_ANDROID) auto offscreenUi = DependencyManager::get(); @@ -4618,6 +4621,7 @@ void Application::idle() { checkChangeCursor(); Stats::getInstance()->updateStats(); + AnimStats::getInstance()->updateStats(); // Normally we check PipelineWarnings, but since idle will often take more than 10ms we only show these idle timing // details if we're in ExtraDebugging mode. However, the ::update() and its subcomponents will show their timing diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index a6ba983ab5..f7be6d17ef 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -737,6 +737,7 @@ Menu::Menu() { // Developer > Stats addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::Stats); + addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::AnimStats); // Settings > Enable Speech Control API #if defined(Q_OS_MAC) || defined(Q_OS_WIN) diff --git a/interface/src/Menu.h b/interface/src/Menu.h index c4ea3734f5..031ee2561c 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -197,6 +197,7 @@ namespace MenuOption { const QString SMIEyeTracking = "SMI Eye Tracking"; const QString SparseTextureManagement = "Enable Sparse Texture Management"; const QString Stats = "Show Statistics"; + const QString AnimStats = "Show Animation Stats"; const QString StopAllScripts = "Stop All Scripts"; const QString SuppressShortTimings = "Suppress Timings Less than 10ms"; const QString ThirdPerson = "Third Person"; diff --git a/interface/src/ui/AnimStats.cpp b/interface/src/ui/AnimStats.cpp new file mode 100644 index 0000000000..7b4778e365 --- /dev/null +++ b/interface/src/ui/AnimStats.cpp @@ -0,0 +1,141 @@ +// +// Created by Anthony J. Thibault 2018/08/06 +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "AnimStats.h" + +#include +#include +#include "Menu.h" + +HIFI_QML_DEF(AnimStats) + +static AnimStats* INSTANCE{ nullptr }; + +AnimStats* AnimStats::getInstance() { + Q_ASSERT(INSTANCE); + return INSTANCE; +} + +AnimStats::AnimStats(QQuickItem* parent) : QQuickItem(parent) { + INSTANCE = this; +} + +void AnimStats::updateStats(bool force) { + QQuickItem* parent = parentItem(); + if (!force) { + if (!Menu::getInstance()->isOptionChecked(MenuOption::AnimStats)) { + if (parent->isVisible()) { + parent->setVisible(false); + } + return; + } else if (!parent->isVisible()) { + parent->setVisible(true); + } + } + + auto avatarManager = DependencyManager::get(); + auto myAvatar = avatarManager->getMyAvatar(); + auto debugAlphaMap = myAvatar->getSkeletonModel()->getRig().getDebugAlphaMap(); + + // update animation debug alpha values + QStringList newAnimAlphaValues; + qint64 now = usecTimestampNow(); + for (auto& iter : debugAlphaMap) { + QString key = iter.first; + float alpha = std::get<0>(iter.second); + + auto prevIter = _prevDebugAlphaMap.find(key); + if (prevIter != _prevDebugAlphaMap.end()) { + float prevAlpha = std::get<0>(iter.second); + if (prevAlpha != alpha) { + // change detected: reset timer + _animAlphaValueChangedTimers[key] = now; + } + } else { + // new value: start timer + _animAlphaValueChangedTimers[key] = now; + } + + AnimNodeType type = std::get<1>(iter.second); + if (type == AnimNodeType::Clip) { + + // figure out the grayScale color of this line. + const float LIT_TIME = 2.0f; + const float FADE_OUT_TIME = 1.0f; + float grayScale = 0.0f; + float secondsElapsed = (float)(now - _animAlphaValueChangedTimers[key]) / (float)USECS_PER_SECOND; + if (secondsElapsed < LIT_TIME) { + grayScale = 1.0f; + } else if (secondsElapsed < LIT_TIME + FADE_OUT_TIME) { + grayScale = (FADE_OUT_TIME - (secondsElapsed - LIT_TIME)) / FADE_OUT_TIME; + } else { + grayScale = 0.0f; + } + + if (grayScale > 0.0f) { + // append grayScaleColor to start of debug string + newAnimAlphaValues << QString::number(grayScale, 'f', 2) + "|" + key + ": " + QString::number(alpha, 'f', 3); + } + } + } + + _animAlphaValues = newAnimAlphaValues; + _prevDebugAlphaMap = debugAlphaMap; + + emit animAlphaValuesChanged(); + + // update animation anim vars + _animVarsList.clear(); + auto animVars = myAvatar->getSkeletonModel()->getRig().getAnimVars().toDebugMap(); + for (auto& iter : animVars) { + QString key = iter.first; + QString value = iter.second; + + auto prevIter = _prevAnimVars.find(key); + if (prevIter != _prevAnimVars.end()) { + QString prevValue = prevIter->second; + if (value != prevValue) { + // change detected: reset timer + _animVarChangedTimers[key] = now; + } + } else { + // new value: start timer + _animVarChangedTimers[key] = now; + } + + // figure out the grayScale color of this line. + const float LIT_TIME = 2.0f; + const float FADE_OUT_TIME = 0.5f; + float grayScale = 0.0f; + float secondsElapsed = (float)(now - _animVarChangedTimers[key]) / (float)USECS_PER_SECOND; + if (secondsElapsed < LIT_TIME) { + grayScale = 1.0f; + } else if (secondsElapsed < LIT_TIME + FADE_OUT_TIME) { + grayScale = (FADE_OUT_TIME - (secondsElapsed - LIT_TIME)) / FADE_OUT_TIME; + } else { + grayScale = 0.0f; + } + + if (grayScale > 0.0f) { + // append grayScaleColor to start of debug string + _animVarsList << QString::number(grayScale, 'f', 2) + "|" + key + ": " + value; + } + } + _prevAnimVars = animVars; + emit animVarsChanged(); + + // animation state machines + _animStateMachines.clear(); + auto stateMachineMap = myAvatar->getSkeletonModel()->getRig().getStateMachineMap(); + for (auto& iter : stateMachineMap) { + _animStateMachines << iter.second; + } + emit animStateMachinesChanged(); +} + + diff --git a/interface/src/ui/AnimStats.h b/interface/src/ui/AnimStats.h new file mode 100644 index 0000000000..1a6795b498 --- /dev/null +++ b/interface/src/ui/AnimStats.h @@ -0,0 +1,55 @@ +// +// Created by Anthony J. Thibault 2018/08/06 +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_AnimStats_h +#define hifi_AnimStats_h + +#include +#include + +class AnimStats : public QQuickItem { + Q_OBJECT + HIFI_QML_DECL + + Q_PROPERTY(QStringList animAlphaValues READ animAlphaValues NOTIFY animAlphaValuesChanged) + Q_PROPERTY(QStringList animVars READ animVars NOTIFY animVarsChanged) + Q_PROPERTY(QStringList animStateMachines READ animStateMachines NOTIFY animStateMachinesChanged) + +public: + static AnimStats* getInstance(); + + AnimStats(QQuickItem* parent = nullptr); + + void updateStats(bool force = false); + + QStringList animAlphaValues() { return _animAlphaValues; } + QStringList animVars() { return _animVarsList; } + QStringList animStateMachines() { return _animStateMachines; } + +public slots: + void forceUpdateStats() { updateStats(true); } + +signals: + + void animAlphaValuesChanged(); + void animVarsChanged(); + void animStateMachinesChanged(); + +private: + QStringList _animAlphaValues; + AnimContext::DebugAlphaMap _prevDebugAlphaMap; // alpha values from previous frame + std::map _animAlphaValueChangedTimers; // last time alpha value has changed + + QStringList _animVarsList; + std::map _prevAnimVars; // anim vars from previous frame + std::map _animVarChangedTimers; // last time animVar value has changed. + + QStringList _animStateMachines; +}; + +#endif // hifi_AnimStats_h diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index 62e44645b9..bfb83f10f8 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -239,7 +239,7 @@ void Stats::updateStats(bool force) { if (secondsElapsed < LIT_TIME) { grayScale = 1.0f; } else if (secondsElapsed < LIT_TIME + FADE_OUT_TIME) { - grayScale = (LIT_TIME - (secondsElapsed - FADE_OUT_TIME)) / LIT_TIME; + grayScale = (FADE_OUT_TIME - (secondsElapsed - LIT_TIME)) / FADE_OUT_TIME; } else { grayScale = 0.0f; } @@ -283,7 +283,7 @@ void Stats::updateStats(bool force) { if (secondsElapsed < LIT_TIME) { grayScale = 1.0f; } else if (secondsElapsed < LIT_TIME + FADE_OUT_TIME) { - grayScale = (LIT_TIME - (secondsElapsed - FADE_OUT_TIME)) / LIT_TIME; + grayScale = (FADE_OUT_TIME - (secondsElapsed - LIT_TIME)) / FADE_OUT_TIME; } else { grayScale = 0.0f; } @@ -296,6 +296,14 @@ void Stats::updateStats(bool force) { _prevAnimVars = animVars; emit animVarsChanged(); + // animation state machines + _animStateMachines.clear(); + auto stateMachineMap = myAvatar->getSkeletonModel()->getRig().getStateMachineMap(); + for (auto& iter : stateMachineMap) { + _animStateMachines << iter.second; + } + emit animStateMachinesChanged(); + glm::vec3 avatarPos = myAvatar->getWorldPosition(); STAT_UPDATE(position, QVector3D(avatarPos.x, avatarPos.y, avatarPos.z)); STAT_UPDATE_FLOAT(speed, glm::length(myAvatar->getWorldVelocity()), 0.01f); diff --git a/interface/src/ui/Stats.h b/interface/src/ui/Stats.h index 3e71c75da1..1febfff8b5 100644 --- a/interface/src/ui/Stats.h +++ b/interface/src/ui/Stats.h @@ -184,6 +184,7 @@ class Stats : public QQuickItem { HIFI_QML_DECL Q_PROPERTY(bool expanded READ isExpanded WRITE setExpanded NOTIFY expandedChanged) Q_PROPERTY(bool timingExpanded READ isTimingExpanded NOTIFY timingExpandedChanged) + Q_PROPERTY(QString monospaceFont READ monospaceFont CONSTANT) STATS_PROPERTY(int, serverCount, 0) @@ -294,6 +295,7 @@ class Stats : public QQuickItem { STATS_PROPERTY(float, avatarSimulationTime, 0) Q_PROPERTY(QStringList animAlphaValues READ animAlphaValues NOTIFY animAlphaValuesChanged) Q_PROPERTY(QStringList animVars READ animVars NOTIFY animVarsChanged) + Q_PROPERTY(QStringList animStateMachines READ animStateMachines NOTIFY animStateMachinesChanged) STATS_PROPERTY(int, stylusPicksCount, 0) STATS_PROPERTY(int, rayPicksCount, 0) @@ -329,6 +331,7 @@ public: QStringList downloadUrls () { return _downloadUrls; } QStringList animAlphaValues() { return _animAlphaValues; } QStringList animVars() { return _animVarsList; } + QStringList animStateMachines() { return _animStateMachines; } public slots: void forceUpdateStats() { updateStats(true); } @@ -1032,6 +1035,7 @@ signals: void animAlphaValuesChanged(); void animVarsChanged(); + void animStateMachinesChanged(); /**jsdoc * Triggered when the value of the rectifiedTextureCount property changes. @@ -1333,15 +1337,17 @@ private: bool _showGameUpdateStats{ false }; QString _monospaceFont; const AudioIOStats* _audioStats; - QStringList _downloadUrls = QStringList(); + QStringList _downloadUrls; - QStringList _animAlphaValues = QStringList(); + QStringList _animAlphaValues; AnimContext::DebugAlphaMap _prevDebugAlphaMap; // alpha values from previous frame std::map _animAlphaValueChangedTimers; // last time alpha value has changed - QStringList _animVarsList = QStringList(); + QStringList _animVarsList; std::map _prevAnimVars; // anim vars from previous frame std::map _animVarChangedTimers; // last time animVar value has changed. + + QStringList _animStateMachines; }; #endif // hifi_Stats_h diff --git a/libraries/animation/src/AnimContext.h b/libraries/animation/src/AnimContext.h index ecfb94a28e..b30421ae84 100644 --- a/libraries/animation/src/AnimContext.h +++ b/libraries/animation/src/AnimContext.h @@ -64,6 +64,19 @@ public: return _debugAlphaMap; } + using DebugStateMachineMapValue = QString; + using DebugStateMachineMap = std::map; + + void addStateMachineInfo(const QString& stateMachineName, const QString& currentState, const QString& previousState, bool duringInterp, float alpha) const { + if (duringInterp) { + _stateMachineMap[stateMachineName] = QString("%1: %2 -> %3 (%4)").arg(stateMachineName).arg(previousState).arg(currentState).arg(QString::number(alpha, 'f', 2)); + } else { + _stateMachineMap[stateMachineName] = QString("%1: %2").arg(stateMachineName).arg(currentState); + } + } + + const DebugStateMachineMap& getStateMachineMap() const { return _stateMachineMap; } + protected: bool _enableDebugDrawIKTargets { false }; @@ -74,6 +87,7 @@ protected: // used for debugging internal state of animation system. mutable DebugAlphaMap _debugAlphaMap; + mutable DebugStateMachineMap _stateMachineMap; }; #endif // hifi_AnimContext_h diff --git a/libraries/animation/src/AnimStateMachine.cpp b/libraries/animation/src/AnimStateMachine.cpp index 00ae5e6d39..7f46cd614a 100644 --- a/libraries/animation/src/AnimStateMachine.cpp +++ b/libraries/animation/src/AnimStateMachine.cpp @@ -87,10 +87,13 @@ const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, co } processOutputJoints(triggersOut); + context.addStateMachineInfo(_id, _currentState->getID(), _previousState->getID(), _duringInterp, _alpha); + return _poses; } void AnimStateMachine::setCurrentState(State::Pointer state) { + _previousState = _currentState ? _currentState : state; _currentState = state; } @@ -135,7 +138,7 @@ void AnimStateMachine::switchState(const AnimVariantMap& animVars, const AnimCon qCDebug(animation) << "AnimStateMachine::switchState:" << _currentState->getID() << "->" << desiredState->getID() << "duration =" << duration << "targetFrame =" << desiredState->_interpTarget << "interpType = " << (int)_interpType; #endif - _currentState = desiredState; + setCurrentState(desiredState); } AnimStateMachine::State::Pointer AnimStateMachine::evaluateTransitions(const AnimVariantMap& animVars) const { diff --git a/libraries/animation/src/AnimStateMachine.h b/libraries/animation/src/AnimStateMachine.h index 8e1e1b7bd8..713c659a1d 100644 --- a/libraries/animation/src/AnimStateMachine.h +++ b/libraries/animation/src/AnimStateMachine.h @@ -140,6 +140,7 @@ protected: AnimPoseVec _nextPoses; State::Pointer _currentState; + State::Pointer _previousState; std::vector _states; QString _currentStateVar; diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 95a4b6f40d..48f00d4e5d 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -225,6 +225,7 @@ public: // used to debug animation playback const AnimContext::DebugAlphaMap& getDebugAlphaMap() const { return _lastContext.getDebugAlphaMap(); } const AnimVariantMap& getAnimVars() const { return _lastAnimVars; } + const AnimContext::DebugStateMachineMap& getStateMachineMap() const { return _lastContext.getStateMachineMap(); } void toggleSmoothPoleVectors() { _smoothPoleVectors = !_smoothPoleVectors; }; signals: From 9e0c21065e0de0d3b75e0f213959d27ca61f6013 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Thu, 6 Sep 2018 15:47:23 -0700 Subject: [PATCH 334/545] Stop sending avatars when over bandwidth quota --- assignment-client/src/avatars/AvatarMixerSlave.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index a61f65ffb0..5dd250fba7 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -425,6 +425,11 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // NOTE: Here's where we determine if we are over budget and drop to bare minimum data int minimRemainingAvatarBytes = minimumBytesPerAvatar * remainingAvatars; bool overBudget = (identityBytesSent + numAvatarDataBytes + minimRemainingAvatarBytes) > maxAvatarBytesPerFrame; + if (overBudget) { + _stats.overBudgetAvatars += remainingAvatars + 1; + overBudgetAvatars += remainingAvatars + 1; + break; + } auto startAvatarDataPacking = chrono::high_resolution_clock::now(); From f59168e1c8b61a143cd0b0de8b672b36d5b00493 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Thu, 6 Sep 2018 16:31:31 -0700 Subject: [PATCH 335/545] make sure ignoredNode is available before sending packet --- assignment-client/src/avatars/AvatarMixer.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index edbba20dc7..561afee296 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -654,6 +654,15 @@ void AvatarMixer::handleNodeIgnoreRequestPacket(QSharedPointer if (addToIgnore) { senderNode->addIgnoredNode(ignoredUUID); + + if (ignoredNode) { + // send a reliable kill packet to remove the sending avatar for the ignored avatar + auto killPacket = NLPacket::create(PacketType::KillAvatar, + NUM_BYTES_RFC4122_UUID + sizeof(KillAvatarReason), true); + killPacket->write(senderNode->getUUID().toRfc4122()); + killPacket->writePrimitive(KillAvatarReason::AvatarDisconnected); + nodeList->sendPacket(std::move(killPacket), *ignoredNode); + } } else { senderNode->removeIgnoredNode(ignoredUUID); } From 92210f28b51403b9ff2a0783c3d9222a46638dd1 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 6 Sep 2018 16:33:30 -0700 Subject: [PATCH 336/545] cleanup and use correct avatar bounding box --- .../src/avatars/AvatarMixerClientData.h | 1 - assignment-client/src/avatars/AvatarMixerSlave.cpp | 14 ++++++-------- libraries/avatars/src/AvatarData.h | 2 +- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixerClientData.h b/assignment-client/src/avatars/AvatarMixerClientData.h index 81a4a58769..64b1ea3edf 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.h +++ b/assignment-client/src/avatars/AvatarMixerClientData.h @@ -91,7 +91,6 @@ public: void loadJSONStats(QJsonObject& jsonObject) const; glm::vec3 getPosition() const { return _avatar ? _avatar->getWorldPosition() : glm::vec3(0); } - glm::vec3 getGlobalBoundingBoxCorner() const { return _avatar ? _avatar->getGlobalBoundingBoxCorner() : glm::vec3(0); } bool isRadiusIgnoring(const QUuid& other) const { return _radiusIgnoredOthers.find(other) != _radiusIgnoredOthers.end(); } void addToRadiusIgnoringSet(const QUuid& other) { _radiusIgnoredOthers.insert(other); } void removeFromRadiusIgnoringSet(const QUuid& other); diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index 3e83a78341..411f77459f 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -213,12 +213,13 @@ void AvatarMixerSlave::broadcastAvatarData(const SharedNodePointer& node) { } AABox computeBubbleBox(const AvatarData& avatar, float bubbleExpansionFactor) { - glm::vec3 position = avatar.getClientGlobalPosition(); - glm::vec3 scale = 2.0f * (avatar.getClientGlobalPosition()- avatar.getGlobalBoundingBoxCorner()); + AABox box = avatar.getGlobalBoundingBox(); + glm::vec3 scale = box.getScale(); scale *= bubbleExpansionFactor; const glm::vec3 MIN_BUBBLE_SCALE(0.3f, 1.3f, 0.3); scale = glm::max(scale, MIN_BUBBLE_SCALE); - return AABox(position - 0.5f * scale, scale); + box.setScaleStayCentered(glm::max(scale, MIN_BUBBLE_SCALE)); + return box; } void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) { @@ -295,7 +296,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) : _avatar(avatar), _node(avatarNode), _lastEncodeTime(lastEncodeTime) {} glm::vec3 getPosition() const override { return _avatar->getClientGlobalPosition(); } float getRadius() const override { - glm::vec3 nodeBoxHalfScale = _avatar->getClientGlobalPosition() - _avatar->getGlobalBoundingBoxCorner(); + glm::vec3 nodeBoxHalfScale = 0.5f * _avatar->getGlobalBoundingBox().getScale(); return glm::max(nodeBoxHalfScale.x, glm::max(nodeBoxHalfScale.y, nodeBoxHalfScale.z)); } uint64_t getTimestamp() const override { @@ -433,10 +434,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) } // determine if avatar is in view which determines how much data to send - glm::vec3 otherPosition = otherAvatar->getClientGlobalPosition(); - glm::vec3 otherNodeBoxScale = otherPosition - otherNodeData->getGlobalBoundingBoxCorner(); - AABox otherNodeBox(otherNodeData->getGlobalBoundingBoxCorner(), otherNodeBoxScale); - bool isInView = nodeData->otherAvatarInView(otherNodeBox); + bool isInView = nodeData->otherAvatarInView(otherAvatar->getGlobalBoundingBox()); // start a new segment in the PacketList for this avatar avatarPacketList->startSegment(); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 0474d07acd..9146340c4d 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -1095,7 +1095,7 @@ public: void fromJson(const QJsonObject& json, bool useFrameSkeleton = true); glm::vec3 getClientGlobalPosition() const { return _globalPosition; } - glm::vec3 getGlobalBoundingBoxCorner() const { return _globalPosition + _globalBoundingBoxOffset - _globalBoundingBoxDimensions; } + AABox getGlobalBoundingBox() const { return AABox(_globalPosition + _globalBoundingBoxOffset - _globalBoundingBoxDimensions, _globalBoundingBoxDimensions); } /**jsdoc * @function MyAvatar.getAvatarEntityData From ed7f993c0dc257132c860d415247215d6349d198 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 6 Sep 2018 16:55:27 -0700 Subject: [PATCH 337/545] avatar mixer and manager perf improvements and cleanup --- .../src/avatars/AvatarMixerSlave.cpp | 45 +++++++++---------- interface/src/avatar/AvatarManager.cpp | 40 ++++++++--------- libraries/avatars/src/AvatarData.cpp | 17 +++---- libraries/avatars/src/AvatarData.h | 2 - libraries/avatars/src/AvatarHashMap.cpp | 1 - libraries/shared/src/PrioritySortUtil.h | 9 ++-- 6 files changed, 50 insertions(+), 64 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index 8afd7d73ee..705d660a2e 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -261,8 +261,6 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // FIXME - find a way to not send the sessionID for every avatar int minimumBytesPerAvatar = AvatarDataPacket::AVATAR_HAS_FLAGS_SIZE + NUM_BYTES_RFC4122_UUID; - int overBudgetAvatars = 0; - // keep track of the number of other avatars held back in this frame int numAvatarsHeldBack = 0; @@ -287,7 +285,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // compute node bounding box const float MY_AVATAR_BUBBLE_EXPANSION_FACTOR = 4.0f; // magic number determined emperically - AABox nodeBox = computeBubbleBox(avatar, MY_AVATAR_BUBBLE_EXPANSION_FACTOR ); + AABox nodeBox = computeBubbleBox(avatar, MY_AVATAR_BUBBLE_EXPANSION_FACTOR); class SortableAvatar: public PrioritySortUtil::Sortable { public: @@ -296,13 +294,12 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) : _avatar(avatar), _node(avatarNode), _lastEncodeTime(lastEncodeTime) {} glm::vec3 getPosition() const override { return _avatar->getClientGlobalPosition(); } float getRadius() const override { - glm::vec3 nodeBoxHalfScale = 0.5f * _avatar->getGlobalBoundingBox().getScale(); - return glm::max(nodeBoxHalfScale.x, glm::max(nodeBoxHalfScale.y, nodeBoxHalfScale.z)); + glm::vec3 nodeBoxScale = _avatar->getGlobalBoundingBox().getScale(); + return 0.5f * glm::max(nodeBoxScale.x, glm::max(nodeBoxScale.y, nodeBoxScale.z)); } uint64_t getTimestamp() const override { return _lastEncodeTime; } - const AvatarData* getAvatar() const { return _avatar; } const Node* getNode() const { return _node; } private: @@ -412,13 +409,19 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) assert(otherNode); // we can't have gotten here without the avatarData being a valid key in the map + AvatarData::AvatarDataDetail detail; + // NOTE: Here's where we determine if we are over budget and drop to bare minimum data int minimRemainingAvatarBytes = minimumBytesPerAvatar * remainingAvatars; bool overBudget = (identityBytesSent + numAvatarDataBytes + minimRemainingAvatarBytes) > maxAvatarBytesPerFrame; if (overBudget) { - _stats.overBudgetAvatars += remainingAvatars + 1; - overBudgetAvatars += remainingAvatars + 1; - break; + if (PALIsOpen) { + _stats.overBudgetAvatars++; + detail = AvatarData::PALMinimum; + } else { + _stats.overBudgetAvatars += remainingAvatars; + break; + } } auto startAvatarDataPacking = chrono::high_resolution_clock::now(); @@ -439,23 +442,13 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) } // determine if avatar is in view which determines how much data to send - bool isInView = nodeData->otherAvatarInView(otherAvatar->getGlobalBoundingBox()); + bool isInView = sortedAvatar.getPriority() > OUT_OF_VIEW_THRESHOLD; - // start a new segment in the PacketList for this avatar - avatarPacketList->startSegment(); - - AvatarData::AvatarDataDetail detail; - - if (overBudget) { - overBudgetAvatars++; - _stats.overBudgetAvatars++; - detail = PALIsOpen ? AvatarData::PALMinimum : AvatarData::NoData; - } else if (!isInView) { + if (!isInView) { detail = PALIsOpen ? AvatarData::PALMinimum : AvatarData::MinimumData; nodeData->incrementAvatarOutOfView(); - } else { - detail = distribution(generator) < AVATAR_SEND_FULL_UPDATE_RATIO - ? AvatarData::SendAllData : AvatarData::CullSmallData; + } else if (!overBudget) { + detail = distribution(generator) < AVATAR_SEND_FULL_UPDATE_RATIO ? AvatarData::SendAllData : AvatarData::CullSmallData; nodeData->incrementAvatarInView(); } @@ -503,8 +496,11 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) } if (includeThisAvatar) { + // start a new segment in the PacketList for this avatar + avatarPacketList->startSegment(); numAvatarDataBytes += avatarPacketList->write(otherNode->getUUID().toRfc4122()); numAvatarDataBytes += avatarPacketList->write(bytes); + avatarPacketList->endSegment(); if (detail != AvatarData::NoData) { _stats.numOthersIncluded++; @@ -522,14 +518,13 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // It would be nice if we could tweak its future sort priority to put it at the back of the list. } - avatarPacketList->endSegment(); - auto endAvatarDataPacking = chrono::high_resolution_clock::now(); _stats.avatarDataPackingElapsedTime += (quint64) chrono::duration_cast(endAvatarDataPacking - startAvatarDataPacking).count(); // use helper to add any changed traits to our packet list traitBytesSent += addChangedTraitsToBulkPacket(nodeData, otherNodeData, *traitsPacketList); + remainingAvatars--; } quint64 startPacketSending = usecTimestampNow(); diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index e9486b9def..1bc22ea98c 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -166,29 +166,29 @@ float AvatarManager::getAvatarSimulationRate(const QUuid& sessionID, const QStri } void AvatarManager::updateOtherAvatars(float deltaTime) { - // lock the hash for read to check the size - QReadLocker lock(&_hashLock); - if (_avatarHash.size() < 2 && _avatarsToFade.isEmpty()) { - return; + { + // lock the hash for read to check the size + QReadLocker lock(&_hashLock); + if (_avatarHash.size() < 2 && _avatarsToFade.isEmpty()) { + return; + } } - lock.unlock(); PerformanceTimer perfTimer("otherAvatars"); class SortableAvatar: public PrioritySortUtil::Sortable { public: SortableAvatar() = delete; - SortableAvatar(const AvatarSharedPointer& avatar) : _avatar(avatar) {} + SortableAvatar(const std::shared_ptr& avatar) : _avatar(avatar) {} glm::vec3 getPosition() const override { return _avatar->getWorldPosition(); } - float getRadius() const override { return std::static_pointer_cast(_avatar)->getBoundingRadius(); } - uint64_t getTimestamp() const override { return std::static_pointer_cast(_avatar)->getLastRenderUpdateTime(); } - AvatarSharedPointer getAvatar() const { return _avatar; } + float getRadius() const override { return _avatar->getBoundingRadius(); } + uint64_t getTimestamp() const override { return _avatar->getLastRenderUpdateTime(); } + std::shared_ptr getAvatar() const { return _avatar; } private: - AvatarSharedPointer _avatar; + std::shared_ptr _avatar; }; auto avatarMap = getHashCopy(); - AvatarHash::iterator itr = avatarMap.begin(); const auto& views = qApp->getConicalViews(); PrioritySortUtil::PriorityQueue sortedAvatars(views, @@ -197,22 +197,24 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { AvatarData::_avatarSortCoefficientAge); sortedAvatars.reserve(avatarMap.size() - 1); // don't include MyAvatar - // sort + // Build vector and compute priorities + auto nodeList = DependencyManager::get(); + AvatarHash::iterator itr = avatarMap.begin(); while (itr != avatarMap.end()) { const auto& avatar = std::static_pointer_cast(*itr); // DO NOT update _myAvatar! Its update has already been done earlier in the main loop. // DO NOT update or fade out uninitialized Avatars - if (avatar != _myAvatar && avatar->isInitialized()) { + if (avatar != _myAvatar && avatar->isInitialized() && !nodeList->isPersonalMutingNode(avatar->getID())) { sortedAvatars.push(SortableAvatar(avatar)); } ++itr; } + // Sort const auto& sortedAvatarVector = sortedAvatars.getSortedVector(); // process in sorted order uint64_t startTime = usecTimestampNow(); - const uint64_t UPDATE_BUDGET = 2000; // usec - uint64_t updateExpiry = startTime + UPDATE_BUDGET; + uint64_t updateExpiry = startTime + MAX_UPDATE_AVATARS_TIME_BUDGET; int numAvatarsUpdated = 0; int numAVatarsNotUpdated = 0; @@ -231,18 +233,12 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { avatar->updateOrbPosition(); } - bool ignoring = DependencyManager::get()->isPersonalMutingNode(avatar->getID()); - if (ignoring) { - continue; - } - // for ALL avatars... if (_shouldRender) { avatar->ensureInScene(avatar, qApp->getMain3DScene()); } avatar->animateScaleChanges(deltaTime); - const float OUT_OF_VIEW_THRESHOLD = 0.5f * AvatarData::OUT_OF_VIEW_PENALTY; uint64_t now = usecTimestampNow(); if (now < updateExpiry) { // we're within budget @@ -263,7 +259,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { // no time to simulate, but we take the time to count how many were tragically missed while (it != sortedAvatarVector.end()) { const SortableAvatar& newSortData = *it; - const auto newAvatar = std::static_pointer_cast(newSortData.getAvatar()); + const auto& newAvatar = newSortData.getAvatar(); bool inView = newSortData.getPriority() > OUT_OF_VIEW_THRESHOLD; // Once we reach an avatar that's not in view, all avatars after it will also be out of view if (!inView) { diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 13adc803dd..038d08145a 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -837,7 +837,6 @@ const unsigned char* unpackFauxJoint(const unsigned char* sourceBuffer, ThreadSa // read data in packet starting at byte offset and return number of bytes parsed int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { - // lazily allocate memory for HeadData in case we're not an Avatar instance lazyInitHeadData(); @@ -889,7 +888,7 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { auto newValue = glm::vec3(data->globalPosition[0], data->globalPosition[1], data->globalPosition[2]) + offset; if (_globalPosition != newValue) { _globalPosition = newValue; - _globalPositionChanged = usecTimestampNow(); + _globalPositionChanged = now; } sourceBuffer += sizeof(AvatarDataPacket::AvatarGlobalPosition); int numBytesRead = sourceBuffer - startSection; @@ -913,11 +912,11 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { if (_globalBoundingBoxDimensions != newDimensions) { _globalBoundingBoxDimensions = newDimensions; - _avatarBoundingBoxChanged = usecTimestampNow(); + _avatarBoundingBoxChanged = now; } if (_globalBoundingBoxOffset != newOffset) { _globalBoundingBoxOffset = newOffset; - _avatarBoundingBoxChanged = usecTimestampNow(); + _avatarBoundingBoxChanged = now; } sourceBuffer += sizeof(AvatarDataPacket::AvatarBoundingBox); @@ -1018,7 +1017,7 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { glm::mat4 sensorToWorldMatrix = createMatFromScaleQuatAndPos(glm::vec3(sensorToWorldScale), sensorToWorldQuat, sensorToWorldTrans); if (_sensorToWorldMatrixCache.get() != sensorToWorldMatrix) { _sensorToWorldMatrixCache.set(sensorToWorldMatrix); - _sensorToWorldMatrixChanged = usecTimestampNow(); + _sensorToWorldMatrixChanged = now; } sourceBuffer += sizeof(AvatarDataPacket::SensorToWorldMatrix); int numBytesRead = sourceBuffer - startSection; @@ -1075,7 +1074,7 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { sourceBuffer += sizeof(AvatarDataPacket::AdditionalFlags); if (somethingChanged) { - _additionalFlagsChanged = usecTimestampNow(); + _additionalFlagsChanged = now; } int numBytesRead = sourceBuffer - startSection; _additionalFlagsRate.increment(numBytesRead); @@ -1095,7 +1094,7 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { if ((getParentID() != newParentID) || (getParentJointIndex() != parentInfo->parentJointIndex)) { SpatiallyNestable::setParentID(newParentID); SpatiallyNestable::setParentJointIndex(parentInfo->parentJointIndex); - _parentChanged = usecTimestampNow(); + _parentChanged = now; } int numBytesRead = sourceBuffer - startSection; @@ -1144,8 +1143,6 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { int numBytesRead = sourceBuffer - startSection; _faceTrackerRate.increment(numBytesRead); _faceTrackerUpdateRate.increment(); - } else { - _headData->_blendshapeCoefficients.fill(0, _headData->_blendshapeCoefficients.size()); } if (hasJointData) { @@ -2820,8 +2817,6 @@ void RayToAvatarIntersectionResultFromScriptValue(const QScriptValue& object, Ra value.extraInfo = object.property("extraInfo").toVariant().toMap(); } -const float AvatarData::OUT_OF_VIEW_PENALTY = -10.0f; - float AvatarData::_avatarSortCoefficientSize { 8.0f }; float AvatarData::_avatarSortCoefficientCenter { 4.0f }; float AvatarData::_avatarSortCoefficientAge { 1.0f }; diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 9146340c4d..cd6440ae5d 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -1167,8 +1167,6 @@ public: // A method intended to be overriden by MyAvatar for polling orientation for network transmission. virtual glm::quat getOrientationOutbound() const; - static const float OUT_OF_VIEW_PENALTY; - // TODO: remove this HACK once we settle on optimal sort coefficients // These coefficients exposed for fine tuning the sort priority for transfering new _jointData to the render pipeline. static float _avatarSortCoefficientSize; diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index c437b56f32..be2ce3d397 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -21,7 +21,6 @@ #include "AvatarLogging.h" #include "AvatarTraits.h" - void AvatarReplicas::addReplica(const QUuid& parentID, AvatarSharedPointer replica) { if (parentID == QUuid()) { return; diff --git a/libraries/shared/src/PrioritySortUtil.h b/libraries/shared/src/PrioritySortUtil.h index 075de13d9d..27f6b193ba 100644 --- a/libraries/shared/src/PrioritySortUtil.h +++ b/libraries/shared/src/PrioritySortUtil.h @@ -18,6 +18,9 @@ // PrioritySortUtil is a helper for sorting 3D things relative to a ViewFrustum. +const float OUT_OF_VIEW_PENALTY = -10.0f; +const float OUT_OF_VIEW_THRESHOLD = 0.5f * OUT_OF_VIEW_PENALTY; + namespace PrioritySortUtil { constexpr float DEFAULT_ANGULAR_COEF { 1.0f }; @@ -93,17 +96,16 @@ namespace PrioritySortUtil { const float MIN_RADIUS = 0.1f; // WORKAROUND for zero size objects (we still want them to sort by distance) float radius = glm::max(thing.getRadius(), MIN_RADIUS); // Other item's angle from view centre: - float cosineAngle = (glm::dot(offset, view.getDirection()) / distance); + float cosineAngle = glm::dot(offset, view.getDirection()) / distance; float age = float((_usecCurrentTime - thing.getTimestamp()) / USECS_PER_SECOND); // the "age" term accumulates at the sum of all weights - float angularSize = glm::max(radius, MIN_RADIUS) / distance; + float angularSize = radius / distance; float priority = (_angularWeight * angularSize + _centerWeight * cosineAngle) * (age + 1.0f) + _ageWeight * age; // decrement priority of things outside keyhole if (distance - radius > view.getRadius()) { if (!view.intersects(offset, distance, radius)) { - constexpr float OUT_OF_VIEW_PENALTY = -10.0f; priority += OUT_OF_VIEW_PENALTY; } } @@ -122,5 +124,6 @@ namespace PrioritySortUtil { // for now we're keeping hard-coded sorted time budgets in one spot const uint64_t MAX_UPDATE_RENDERABLES_TIME_BUDGET = 2000; // usec const uint64_t MIN_SORTED_UPDATE_RENDERABLES_TIME_BUDGET = 1000; // usec +const uint64_t MAX_UPDATE_AVATARS_TIME_BUDGET = 2000; // usec #endif // hifi_PrioritySortUtil_h From 2f9119529a67209d0adcfda189ddd6859d52a80f Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Thu, 6 Sep 2018 17:06:17 -0700 Subject: [PATCH 338/545] editing the interstitial page --- interface/src/Application.cpp | 7 ++----- interface/src/Menu.cpp | 1 - scripts/defaultScripts.js | 3 ++- scripts/system/interstitialPage.js | 30 ++++++++++++++++-------------- 4 files changed, 20 insertions(+), 21 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 73e2fce956..15416b26cb 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3488,14 +3488,11 @@ bool Application::isServerlessMode() const { } bool Application::isInterstitialMode() const { - bool interstitialModeEnabled = Menu::getInstance()->isOptionChecked("Enable Interstitial"); - return interstitialModeEnabled ? _interstitialMode : false; + return _interstitialMode; } void Application::setIsInterstitialMode(bool interstitialMode) { - auto menu = Menu::getInstance(); - bool interstitialModeEnabled = menu->isOptionChecked("Enable Interstitial"); - if (_interstitialMode != interstitialMode && interstitialModeEnabled) { + if (_interstitialMode != interstitialMode) { _interstitialMode = interstitialMode; emit interstitialModeChanged(_interstitialMode); } diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 15898a73b1..a6ba983ab5 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -787,7 +787,6 @@ Menu::Menu() { // Developer > Show Overlays addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::Overlays, 0, true); - addCheckableActionToQMenuAndActionHash(developerMenu, "Enable Interstitial", 0, false); #if 0 /// -------------- REMOVED FOR NOW -------------- addDisabledActionAndSeparator(navigateMenu, "History"); diff --git a/scripts/defaultScripts.js b/scripts/defaultScripts.js index c333a0c8c2..31510831c8 100644 --- a/scripts/defaultScripts.js +++ b/scripts/defaultScripts.js @@ -34,7 +34,8 @@ var DEFAULT_SCRIPTS_COMBINED = [ "system/emote.js" ]; var DEFAULT_SCRIPTS_SEPARATE = [ - "system/controllers/controllerScripts.js" + "system/controllers/controllerScripts.js", + "system/interstitialPage.js" //"system/chat.js" ]; diff --git a/scripts/system/interstitialPage.js b/scripts/system/interstitialPage.js index c95845656c..aa84fed476 100644 --- a/scripts/system/interstitialPage.js +++ b/scripts/system/interstitialPage.js @@ -14,8 +14,9 @@ (function() { Script.include("/~/system/libraries/Xform.js"); - var DEBUG = false; - var MAX_X_SIZE = 3.8; + var DEBUG = true; + var MIN_LOADING_PROGRESS = 3.6; + var TOTAL_LOADING_PROGRESS = 3.8; var EPSILON = 0.01; var isVisible = false; var VOLUME = 0.4; @@ -55,7 +56,7 @@ "Tip: Log in to make friends, visit new domains, and save avatars!" ]; - var DEFAULT_DIMENSIONS = { x: 20, y: 20, z: 20 }; + var DEFAULT_DIMENSIONS = { x: 24, y: 24, z: 24 }; var loadingSphereID = Overlays.addOverlay("model", { name: "Loading-Sphere", @@ -87,10 +88,10 @@ var domainName = ""; var domainNameTextID = Overlays.addOverlay("text3d", { name: "Loading-Destination-Card-Text", - localPosition: { x: 0.0, y: 0.8, z: 0.0 }, + localPosition: { x: 0.0, y: 0.8, z: -0.001 }, text: domainName, textAlpha: 1, - backgroundAlpha: 0, + backgroundAlpha: 1, lineHeight: 0.42, visible: isVisible, ignoreRayIntersection: true, @@ -106,9 +107,10 @@ localPosition: { x: 0.0, y: 0.32, z: 0.0 }, text: domainText, textAlpha: 1, - backgroundAlpha: 0, + backgroundAlpha: 1, lineHeight: 0.13, visible: isVisible, + backgroundAlpha: 0, ignoreRayIntersection: true, drawInFront: true, grabbable: false, @@ -123,7 +125,7 @@ localPosition: { x: 0.0 , y: -1.6, z: 0.0 }, text: toolTip, textAlpha: 1, - backgroundAlpha: 0, + backgroundAlpha: 1, lineHeight: 0.13, visible: isVisible, ignoreRayIntersection: true, @@ -248,7 +250,6 @@ } function domainChanged(domain) { - print("domain changed: " + domain); if (domain !== currentDomain) { MyAvatar.restoreAnimation(); var name = location.placename; @@ -272,7 +273,6 @@ if (data.status === "success") { var domainInfo = data.data; var domainDescriptionText = domainInfo.place.description; - print("domainText: " + domainDescriptionText); var leftMargin = getLeftMargin(domainDescription, domainDescriptionText); var domainDescriptionProperties = { text: domainDescriptionText, @@ -381,18 +381,18 @@ var domainLoadingProgressPercentage = Window.domainLoadingProgress(); - var progress = MAX_X_SIZE * domainLoadingProgressPercentage; + var progress = MIN_LOADING_PROGRESS * domainLoadingProgressPercentage; if (progress >= target) { target = progress; } - if ((physicsEnabled && (currentProgress < MAX_X_SIZE))) { - target = MAX_X_SIZE; + if ((physicsEnabled && (currentProgress < TOTAL_LOADING_PROGRESS))) { + target = TOTAL_LOADING_PROGRESS; } currentProgress = lerp(currentProgress, target, 0.2); var properties = { - localPosition: { x: (1.85 - (currentProgress / 2) - (-0.029 * (currentProgress / MAX_X_SIZE))), y: -0.935, z: 0.0 }, + localPosition: { x: (1.85 - (currentProgress / 2) - (-0.029 * (currentProgress / TOTAL_LOADING_PROGRESS))), y: -0.935, z: 0.0 }, dimensions: { x: currentProgress, y: 2.8 @@ -400,9 +400,10 @@ }; Overlays.editOverlay(loadingBarProgress, properties); - if ((physicsEnabled && (currentProgress >= (MAX_X_SIZE - EPSILON)))) { + if ((physicsEnabled && (currentProgress >= (TOTAL_LOADING_PROGRESS - EPSILON)))) { updateOverlays((physicsEnabled || connectionToDomainFailed)); endAudio(); + currentDomain = "no domain"; timer = null; return; } @@ -452,6 +453,7 @@ renderViewTask.getConfig("LightingModel")["enableAmbientLight"] = true; renderViewTask.getConfig("LightingModel")["enableDirectionalLight"] = true; renderViewTask.getConfig("LightingModel")["enablePointLight"] = true; + Menu.setIsOptionChecked("Show Overlays", physicsEnabled); if (!HMD.active) { toolbar.writeProperty("visible", true); } From 22df1b3bc699c1917a5b43530e4ab60b5a06d604 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 6 Sep 2018 17:00:12 -0700 Subject: [PATCH 339/545] Add comment to Assets.sendFakeHandshake about excluding jsdoc --- libraries/script-engine/src/AssetScriptingInterface.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/script-engine/src/AssetScriptingInterface.h b/libraries/script-engine/src/AssetScriptingInterface.h index 72d6901fb5..0e05a563b2 100644 --- a/libraries/script-engine/src/AssetScriptingInterface.h +++ b/libraries/script-engine/src/AssetScriptingInterface.h @@ -108,6 +108,10 @@ public: Q_INVOKABLE void setBakingEnabled(QString path, bool enabled, QScriptValue callback); #if (PR_BUILD || DEV_BUILD) + /** + * This function is purely for development purposes, and not meant for use in a + * production context. It is not a public-facing API, so it should not contain jsdoc. + */ Q_INVOKABLE void sendFakedHandshake(); #endif From e76ebf7a0b8a4207436c04d7a30aef1d14919b1b Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Thu, 6 Sep 2018 17:29:16 -0700 Subject: [PATCH 340/545] changing location of shortcuts --- .../LoginDialog/+android/LinkAccountBody.qml | 40 ++++----- .../qml/LoginDialog/LinkAccountBody.qml | 87 ++++++++++--------- 2 files changed, 66 insertions(+), 61 deletions(-) diff --git a/interface/resources/qml/LoginDialog/+android/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/+android/LinkAccountBody.qml index bf7807c85d..96b638c911 100644 --- a/interface/resources/qml/LoginDialog/+android/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/+android/LinkAccountBody.qml @@ -117,27 +117,27 @@ Item { } spacing: hifi.dimensions.contentSpacing.y / 2 - TextField { - id: usernameField - anchors { - horizontalCenter: parent.horizontalCenter - } - width: 1080 - placeholderText: qsTr("Username or Email") + TextField { + id: usernameField + anchors { + horizontalCenter: parent.horizontalCenter } + width: 1080 + placeholderText: qsTr("Username or Email") + } - TextField { - id: passwordField - anchors { - horizontalCenter: parent.horizontalCenter - } - width: 1080 - - placeholderText: qsTr("Password") - echoMode: TextInput.Password - - Keys.onReturnPressed: linkAccountBody.login() + TextField { + id: passwordField + anchors { + horizontalCenter: parent.horizontalCenter } + width: 1080 + + placeholderText: qsTr("Password") + echoMode: TextInput.Password + + Keys.onReturnPressed: linkAccountBody.login() + } } InfoItem { @@ -176,7 +176,7 @@ Item { anchors { left: parent.left top: form.bottom - topMargin: hifi.dimensions.contentSpacing.y / 2 + topMargin: hifi.dimensions.contentSpacing.y / 2 } spacing: hifi.dimensions.contentSpacing.x @@ -201,7 +201,7 @@ Item { anchors { right: parent.right top: form.bottom - topMargin: hifi.dimensions.contentSpacing.y / 2 + topMargin: hifi.dimensions.contentSpacing.y / 2 } spacing: hifi.dimensions.contentSpacing.x onHeightChanged: d.resize(); onWidthChanged: d.resize(); diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index 902466270f..2274d88e04 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -15,13 +15,14 @@ import QtQuick.Controls.Styles 1.4 as OriginalStyles import "../controls-uit" import "../styles-uit" - Item { id: linkAccountBody clip: true height: root.pane.height width: root.pane.width property bool failAfterSignUp: false + property var locale: Qt.locale() + property string dateTimeString function login() { mainTextContainer.visible = false @@ -124,29 +125,27 @@ Item { placeholderText: "Username or Email" activeFocusOnPress: true + ShortcutText { + z: 10 + y: usernameField.height + anchors { + right: usernameField.right + topMargin: -19 + } + + text: "Forgot Username?" + + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + linkColor: hifi.colors.blueAccent + + onLinkActivated: loginDialog.openUrl(link) + } + onFocusChanged: { root.text = ""; } } - ShortcutText { - id: forgotUsernameShortcut - z: 10 - anchors { - leftMargin: usernameField.textFieldLabel.contentWidth + 10 - topMargin: -19 - } - - text: "Forgot Username?" - - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignRight - linkColor: hifi.colors.blueAccent - - onLinkActivated: loginDialog.openUrl(link) - Component.onCompleted: { - forgotUsernameShortcut.x = root.implicitWidth - forgotUsernameShortcut.width; - } - } TextField { id: passwordField @@ -154,11 +153,30 @@ Item { placeholderText: "Password" activeFocusOnPress: true echoMode: TextInput.Password + onHeightChanged: d.resize(); onWidthChanged: d.resize(); + + ShortcutText { + id: forgotPasswordShortcut + y: passwordField.height + z: 10 + anchors { + right: passwordField.right + } + + text: "Forgot Password?" + + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + linkColor: hifi.colors.blueAccent + + onLinkActivated: loginDialog.openUrl(link) + } onFocusChanged: { root.text = ""; root.isPassword = true; } + Image { id: showPasswordImage x: parent.width - ((parent.height) * 31 / 23) @@ -190,7 +208,6 @@ Item { showPasswordImage.y = showPassword ? 0 : (passwordField.height - showPasswordImage.height) / 2; showPasswordHitbox.width = showPasswordImage.width; showPasswordHitbox.x = showPasswordImage.x; - } } } @@ -198,26 +215,6 @@ Item { Keys.onReturnPressed: linkAccountBody.login() } - ShortcutText { - id: forgotPasswordShortcut - z: 10 - anchors { - leftMargin: passwordField.textFieldLabel.contentWidth + 10 - topMargin: -19 - } - - text: "Forgot Password?" - - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - linkColor: hifi.colors.blueAccent - - onLinkActivated: loginDialog.openUrl(link) - Component.onCompleted: { - forgotPasswordShortcut.x = root.implicitWidth - forgotPasswordShortcut.width; - } - } - InfoItem { id: additionalInformation @@ -304,6 +301,14 @@ Item { } usernameField.forceActiveFocus(); + + var data = { + "date": new Date().toLocaleString(), + }; + print(new Date().toLocaleString()); + print(model.sessionId); + + //UserActivityLogger.logAction("login_screen_shown", ) } Connections { From 45a99a9244679da6d30ba489b6a225a0be4ad1d4 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Thu, 6 Sep 2018 17:55:10 -0700 Subject: [PATCH 341/545] fixing some bugs --- scripts/system/interstitialPage.js | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/scripts/system/interstitialPage.js b/scripts/system/interstitialPage.js index aa84fed476..1cc048ca99 100644 --- a/scripts/system/interstitialPage.js +++ b/scripts/system/interstitialPage.js @@ -14,7 +14,7 @@ (function() { Script.include("/~/system/libraries/Xform.js"); - var DEBUG = true; + var DEBUG = false; var MIN_LOADING_PROGRESS = 3.6; var TOTAL_LOADING_PROGRESS = 3.8; var EPSILON = 0.01; @@ -410,8 +410,21 @@ timer = Script.setTimeout(update, BASIC_TIMER_INTERVAL_MS); } - + var whiteColor = {red: 255, green: 255, blue: 255}; + var greyColor = {red: 125, green: 125, blue: 125}; Overlays.mouseReleaseOnOverlay.connect(clickedOnOverlay); + Overlays.hoverEnterOverlay.connect(function(overlayID, event) { + if (overlayID === loadingToTheSpotID) { + Overlays.editOverlay(loadingToTheSpotID, { color: greyColor}); + } + }); + + Overlays.hoverLeaveOverlay.connect(function(overlayID, event) { + if (overlayID === loadingToTheSpotID) { + Overlays.editOverlay(loadingToTheSpotID, { color: whiteColor}); + } + }); + location.hostChanged.connect(domainChanged); location.lookupResultsFinished.connect(function() { Script.setTimeout(function() { @@ -453,7 +466,7 @@ renderViewTask.getConfig("LightingModel")["enableAmbientLight"] = true; renderViewTask.getConfig("LightingModel")["enableDirectionalLight"] = true; renderViewTask.getConfig("LightingModel")["enablePointLight"] = true; - Menu.setIsOptionChecked("Show Overlays", physicsEnabled); + Menu.setIsOptionChecked("Show Overlays", true); if (!HMD.active) { toolbar.writeProperty("visible", true); } From 6508533a15fd3035593535ae87bdb6316b8d6eb1 Mon Sep 17 00:00:00 2001 From: Anthony Thibault Date: Thu, 6 Sep 2018 17:58:40 -0700 Subject: [PATCH 342/545] Remove anim stats from plain ole stats. There are still present in anim stats tho. --- interface/resources/qml/Stats.qml | 83 -------------------------- interface/src/ui/Stats.cpp | 98 ------------------------------- interface/src/ui/Stats.h | 25 +------- 3 files changed, 1 insertion(+), 205 deletions(-) diff --git a/interface/resources/qml/Stats.qml b/interface/resources/qml/Stats.qml index f74f0539c9..1a29ce87df 100644 --- a/interface/resources/qml/Stats.qml +++ b/interface/resources/qml/Stats.qml @@ -192,89 +192,6 @@ Item { StatText { text: "Yaw: " + root.yaw.toFixed(1) } - StatText { - visible: root.animStateMachines.length > 0; - text: "Anim State Machines:" - } - ListView { - width: geoCol.width - height: root.animStateMachines.length * 15 - visible: root.animStateMchines.length > 0; - model: root.animStateMachines - delegate: StatText { - text: { - if (modelData.length > 30) { - return modelData.substring(0, 5) + "..." + modelData.substring(.length - 22); - } else { - return modelData; - } - } - } - } - StatText { - visible: root.animAlphaValues.length > 0; - text: "Anim Alpha Values:" - } - ListView { - width: geoCol.width - height: root.animAlphaValues.length * 15 - visible: root.animAlphaValues.length > 0; - model: root.animAlphaValues - delegate: StatText { - text: { - var actualText = modelData.split("|")[1]; - if (actualText) { - if (actualText.length > 30) { - return actualText.substring(0, 5) + "..." + actualText.substring(actualText.length - 22); - } else { - return actualText; - } - } else { - return modelData; - } - } - color: { - var grayScale = parseFloat(modelData.split("|")[0]); - return Qt.rgba(1.0, 1.0, 1.0, grayScale); - } - styleColor: { - var grayScale = parseFloat(modelData.split("|")[0]); - return Qt.rgba(0.0, 0.0, 0.0, grayScale); - } - } - } - StatText { - visible: root.animVars.length > 0; - text: "AnimVars:" - } - ListView { - width: geoCol.width - height: root.animVars.length * 15 - visible: root.animVars.length > 0; - model: root.animVars - delegate: StatText { - text: { - var actualText = modelData.split("|")[1]; - if (actualText) { - if (actualText.length > 30) { - return actualText.substring(0, 5) + "..." + actualText.substring(actualText.length - 22); - } else { - return actualText; - } - } else { - return modelData; - } - } - color: { - var grayScale = parseFloat(modelData.split("|")[0]); - return Qt.rgba(1.0, 1.0, 1.0, grayScale); - } - styleColor: { - var grayScale = parseFloat(modelData.split("|")[0]); - return Qt.rgba(0.0, 0.0, 0.0, grayScale); - } - } - } StatText { visible: root.expanded; text: "Avatar Mixer In: " + root.avatarMixerInKbps + " kbps, " + diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index bfb83f10f8..d51b90f15d 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -207,103 +207,6 @@ void Stats::updateStats(bool force) { // Third column, avatar stats auto myAvatar = avatarManager->getMyAvatar(); - auto debugAlphaMap = myAvatar->getSkeletonModel()->getRig().getDebugAlphaMap(); - - // update animation debug alpha values - QStringList newAnimAlphaValues; - qint64 now = usecTimestampNow(); - for (auto& iter : debugAlphaMap) { - QString key = iter.first; - float alpha = std::get<0>(iter.second); - - auto prevIter = _prevDebugAlphaMap.find(key); - if (prevIter != _prevDebugAlphaMap.end()) { - float prevAlpha = std::get<0>(iter.second); - if (prevAlpha != alpha) { - // change detected: reset timer - _animAlphaValueChangedTimers[key] = now; - } - } else { - // new value: start timer - _animAlphaValueChangedTimers[key] = now; - } - - AnimNodeType type = std::get<1>(iter.second); - if (type == AnimNodeType::Clip) { - - // figure out the grayScale color of this line. - const float LIT_TIME = 2.0f; - const float FADE_OUT_TIME = 1.0f; - float grayScale = 0.0f; - float secondsElapsed = (float)(now - _animAlphaValueChangedTimers[key]) / (float)USECS_PER_SECOND; - if (secondsElapsed < LIT_TIME) { - grayScale = 1.0f; - } else if (secondsElapsed < LIT_TIME + FADE_OUT_TIME) { - grayScale = (FADE_OUT_TIME - (secondsElapsed - LIT_TIME)) / FADE_OUT_TIME; - } else { - grayScale = 0.0f; - } - - if (grayScale > 0.0f) { - // append grayScaleColor to start of debug string - newAnimAlphaValues << QString::number(grayScale, 'f', 2) + "|" + key + ": " + QString::number(alpha, 'f', 3); - } - } - } - - _animAlphaValues = newAnimAlphaValues; - _prevDebugAlphaMap = debugAlphaMap; - - emit animAlphaValuesChanged(); - - // update animation anim vars - _animVarsList.clear(); - auto animVars = myAvatar->getSkeletonModel()->getRig().getAnimVars().toDebugMap(); - for (auto& iter : animVars) { - QString key = iter.first; - QString value = iter.second; - - auto prevIter = _prevAnimVars.find(key); - if (prevIter != _prevAnimVars.end()) { - QString prevValue = prevIter->second; - if (value != prevValue) { - // change detected: reset timer - _animVarChangedTimers[key] = now; - } - } else { - // new value: start timer - _animVarChangedTimers[key] = now; - } - - // figure out the grayScale color of this line. - const float LIT_TIME = 2.0f; - const float FADE_OUT_TIME = 0.5f; - float grayScale = 0.0f; - float secondsElapsed = (float)(now - _animVarChangedTimers[key]) / (float)USECS_PER_SECOND; - if (secondsElapsed < LIT_TIME) { - grayScale = 1.0f; - } else if (secondsElapsed < LIT_TIME + FADE_OUT_TIME) { - grayScale = (FADE_OUT_TIME - (secondsElapsed - LIT_TIME)) / FADE_OUT_TIME; - } else { - grayScale = 0.0f; - } - - if (grayScale > 0.0f) { - // append grayScaleColor to start of debug string - _animVarsList << QString::number(grayScale, 'f', 2) + "|" + key + ": " + value; - } - } - _prevAnimVars = animVars; - emit animVarsChanged(); - - // animation state machines - _animStateMachines.clear(); - auto stateMachineMap = myAvatar->getSkeletonModel()->getRig().getStateMachineMap(); - for (auto& iter : stateMachineMap) { - _animStateMachines << iter.second; - } - emit animStateMachinesChanged(); - glm::vec3 avatarPos = myAvatar->getWorldPosition(); STAT_UPDATE(position, QVector3D(avatarPos.x, avatarPos.y, avatarPos.z)); STAT_UPDATE_FLOAT(speed, glm::length(myAvatar->getWorldVelocity()), 0.01f); @@ -436,7 +339,6 @@ void Stats::updateStats(bool force) { } sendingModeStream << "] " << serverCount << " servers"; if (movingServerCount > 0) { - sendingModeStream << " "; } else { sendingModeStream << " "; diff --git a/interface/src/ui/Stats.h b/interface/src/ui/Stats.h index 1febfff8b5..ae608cfddb 100644 --- a/interface/src/ui/Stats.h +++ b/interface/src/ui/Stats.h @@ -14,7 +14,6 @@ #include #include #include -#include #define STATS_PROPERTY(type, name, initialValue) \ Q_PROPERTY(type name READ name NOTIFY name##Changed) \ @@ -184,7 +183,6 @@ class Stats : public QQuickItem { HIFI_QML_DECL Q_PROPERTY(bool expanded READ isExpanded WRITE setExpanded NOTIFY expandedChanged) Q_PROPERTY(bool timingExpanded READ isTimingExpanded NOTIFY timingExpandedChanged) - Q_PROPERTY(QString monospaceFont READ monospaceFont CONSTANT) STATS_PROPERTY(int, serverCount, 0) @@ -293,9 +291,6 @@ class Stats : public QQuickItem { STATS_PROPERTY(float, batchFrameTime, 0) STATS_PROPERTY(float, engineFrameTime, 0) STATS_PROPERTY(float, avatarSimulationTime, 0) - Q_PROPERTY(QStringList animAlphaValues READ animAlphaValues NOTIFY animAlphaValuesChanged) - Q_PROPERTY(QStringList animVars READ animVars NOTIFY animVarsChanged) - Q_PROPERTY(QStringList animStateMachines READ animStateMachines NOTIFY animStateMachinesChanged) STATS_PROPERTY(int, stylusPicksCount, 0) STATS_PROPERTY(int, rayPicksCount, 0) @@ -329,9 +324,6 @@ public: } QStringList downloadUrls () { return _downloadUrls; } - QStringList animAlphaValues() { return _animAlphaValues; } - QStringList animVars() { return _animVarsList; } - QStringList animStateMachines() { return _animStateMachines; } public slots: void forceUpdateStats() { updateStats(true); } @@ -1033,10 +1025,6 @@ signals: */ void avatarSimulationTimeChanged(); - void animAlphaValuesChanged(); - void animVarsChanged(); - void animStateMachinesChanged(); - /**jsdoc * Triggered when the value of the rectifiedTextureCount property changes. * @function Stats.rectifiedTextureCountChanged @@ -1051,7 +1039,6 @@ signals: */ void decimatedTextureCountChanged(); - // QQuickItem signals. /**jsdoc @@ -1337,17 +1324,7 @@ private: bool _showGameUpdateStats{ false }; QString _monospaceFont; const AudioIOStats* _audioStats; - QStringList _downloadUrls; - - QStringList _animAlphaValues; - AnimContext::DebugAlphaMap _prevDebugAlphaMap; // alpha values from previous frame - std::map _animAlphaValueChangedTimers; // last time alpha value has changed - - QStringList _animVarsList; - std::map _prevAnimVars; // anim vars from previous frame - std::map _animVarChangedTimers; // last time animVar value has changed. - - QStringList _animStateMachines; + QStringList _downloadUrls = QStringList(); }; #endif // hifi_Stats_h From 22cfad248310788459d594c874d7c5fee1bce902 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Thu, 6 Sep 2018 18:32:37 -0700 Subject: [PATCH 343/545] Squelch (false) warning from gcc --- 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 705d660a2e..784205a2da 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -409,7 +409,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) assert(otherNode); // we can't have gotten here without the avatarData being a valid key in the map - AvatarData::AvatarDataDetail detail; + AvatarData::AvatarDataDetail detail = AvatarData::NoData; // NOTE: Here's where we determine if we are over budget and drop to bare minimum data int minimRemainingAvatarBytes = minimumBytesPerAvatar * remainingAvatars; From 2443723a2bfc324d69e5270e062e699a299c4177 Mon Sep 17 00:00:00 2001 From: Alexia Mandeville Date: Thu, 6 Sep 2018 21:14:04 -0700 Subject: [PATCH 344/545] Removing margins, adding width attribute --- interface/resources/qml/LoginDialog/LinkAccountBody.qml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index d2a97874b1..707c173382 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -97,6 +97,7 @@ Item { } text: qsTr("Sign in to High Fidelity to make friends, get HFC, and buy interesting things on the Marketplace!") + width: parent.width wrapMode: Text.WordWrap lineHeight: 1 lineHeightMode: Text.ProportionalHeight @@ -146,7 +147,6 @@ Item { anchors { right: usernameField.right top: usernameField.bottom - topMargin: -19 } text: "Forgot Username?" @@ -174,7 +174,6 @@ Item { anchors { right: passwordField.right top: passwordField.bottom - topMargin: -19 } text: "Forgot Password?" From 92f218ae29a24edb8ef7a56a62e83a7201998474 Mon Sep 17 00:00:00 2001 From: Alexia Mandeville Date: Thu, 6 Sep 2018 22:59:19 -0700 Subject: [PATCH 345/545] Adding margins to forgotten link text --- interface/resources/qml/LoginDialog/LinkAccountBody.qml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index 707c173382..90437c008e 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -147,6 +147,7 @@ Item { anchors { right: usernameField.right top: usernameField.bottom + topMargin: 2 } text: "Forgot Username?" @@ -174,6 +175,7 @@ Item { anchors { right: passwordField.right top: passwordField.bottom + topMargin: 2 } text: "Forgot Password?" From 190a335c7118be684db1e86369759207e16cc29a Mon Sep 17 00:00:00 2001 From: Alexia Mandeville Date: Fri, 7 Sep 2018 00:01:00 -0700 Subject: [PATCH 346/545] Adding more margin to forgotten links --- interface/resources/qml/LoginDialog/LinkAccountBody.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index 90437c008e..28523617b6 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -147,7 +147,7 @@ Item { anchors { right: usernameField.right top: usernameField.bottom - topMargin: 2 + topMargin: 4 } text: "Forgot Username?" @@ -175,7 +175,7 @@ Item { anchors { right: passwordField.right top: passwordField.bottom - topMargin: 2 + topMargin: 4 } text: "Forgot Password?" From 7058b07aea05226b33b769d18b7ea02c1ebbc39b Mon Sep 17 00:00:00 2001 From: Alexander Ivash Date: Fri, 7 Sep 2018 12:41:27 +0300 Subject: [PATCH 347/545] FB18024: 2 users report that while in VR and in GoTo menu, keyboard is unable to be minimized --- interface/resources/qml/hifi/tablet/TabletAddressDialog.qml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml index c9d05aea51..802c00a97a 100644 --- a/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml +++ b/interface/resources/qml/hifi/tablet/TabletAddressDialog.qml @@ -105,7 +105,6 @@ StackView { propagateComposedEvents: true onPressed: { parent.forceActiveFocus(); - addressBarDialog.keyboardEnabled = false; mouse.accepted = false; } } @@ -223,7 +222,6 @@ StackView { updateLocationText(text.length > 0); } onAccepted: { - addressBarDialog.keyboardEnabled = false; toggleOrGo(); } @@ -378,7 +376,7 @@ StackView { HifiControls.Keyboard { id: keyboard - raised: parent.keyboardEnabled + raised: parent.keyboardEnabled && parent.keyboardRaised numeric: parent.punctuationMode anchors { bottom: parent.bottom From 5a059e93184acc28e21262b8080c6341a7559403 Mon Sep 17 00:00:00 2001 From: Anthony Thibault Date: Fri, 7 Sep 2018 09:44:19 -0700 Subject: [PATCH 348/545] Fix for build failure on linux and android. --- libraries/animation/src/AnimContext.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/animation/src/AnimContext.h b/libraries/animation/src/AnimContext.h index b30421ae84..c455dd9c8f 100644 --- a/libraries/animation/src/AnimContext.h +++ b/libraries/animation/src/AnimContext.h @@ -14,8 +14,8 @@ #include #include -#include -#include +#include +#include #include enum class AnimNodeType { From 3dc993c841566027c7409ca29b98cb35a7e08701 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Fri, 7 Sep 2018 09:46:21 -0700 Subject: [PATCH 349/545] Fix small error in translation delta --- libraries/avatars/src/AvatarData.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 905569cb65..04efcb242e 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -625,7 +625,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent destinationBuffer += numValidityBytes; // Move pointer past the validity bytes - float minTranslation = (distanceAdjust && cullSmallChanges) ? getDistanceBasedMinTranslationDistance(viewerPosition) : AVATAR_MIN_ROTATION_DOT; + float minTranslation = (distanceAdjust && cullSmallChanges) ? getDistanceBasedMinTranslationDistance(viewerPosition) : AVATAR_MIN_TRANSLATION; float maxTranslationDimension = 0.0; for (int i = 0; i < jointData.size(); i++) { From d979d02139158069201b489ad5a9e674a8cee951 Mon Sep 17 00:00:00 2001 From: sam gateau Date: Fri, 7 Sep 2018 10:03:55 -0700 Subject: [PATCH 350/545] why did i do that? --- libraries/gpu-gl-common/src/gpu/gl/GLBuffer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBuffer.h b/libraries/gpu-gl-common/src/gpu/gl/GLBuffer.h index b9fe125c8d..6b7d3405f0 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBuffer.h +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBuffer.h @@ -65,7 +65,7 @@ public: ~GLBuffer(); - virtual void transfer() {}; + virtual void transfer() = 0; protected: GLBuffer(const std::weak_ptr& backend, const Buffer& buffer, GLuint id); From f9ec53a2e6ac9bcd64d5ab0d53c2c868aa7fde27 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 7 Sep 2018 10:25:26 -0700 Subject: [PATCH 351/545] fix bloom on edges --- libraries/render-utils/src/DeferredFramebuffer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/render-utils/src/DeferredFramebuffer.cpp b/libraries/render-utils/src/DeferredFramebuffer.cpp index 2df89b8808..1906375654 100644 --- a/libraries/render-utils/src/DeferredFramebuffer.cpp +++ b/libraries/render-utils/src/DeferredFramebuffer.cpp @@ -73,7 +73,7 @@ void DeferredFramebuffer::allocate() { _deferredFramebufferDepthColor->setDepthStencilBuffer(_primaryDepthTexture, depthFormat); - auto smoothSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT); + auto smoothSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT, gpu::Sampler::WRAP_CLAMP); _lightingTexture = gpu::Texture::createRenderBuffer(gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::R11G11B10), width, height, gpu::Texture::SINGLE_MIP, smoothSampler); _lightingFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("lighting")); From dd6801219b098bf028bfae60b8b78030846878de Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Fri, 7 Sep 2018 19:54:26 +0200 Subject: [PATCH 352/545] Create entities from avatar a bit lower to be able to transform them away from the user easier --- scripts/system/edit.js | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/system/edit.js b/scripts/system/edit.js index e340c75a8b..ed2a179613 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -1739,7 +1739,6 @@ function getPositionToCreateEntity(extra) { position = Vec3.sum(Camera.position, Vec3.multiply(Quat.getForward(Camera.orientation), CREATE_DISTANCE + delta)); } else { position = Vec3.sum(MyAvatar.position, Vec3.multiply(Quat.getForward(MyAvatar.orientation), CREATE_DISTANCE + delta)); - position.y += 0.5; } if (position.x > HALF_TREE_SCALE || position.y > HALF_TREE_SCALE || position.z > HALF_TREE_SCALE) { From fa72910ac13b7876dcfe606aa38aa262cb38f640 Mon Sep 17 00:00:00 2001 From: sam gateau Date: Fri, 7 Sep 2018 11:14:12 -0700 Subject: [PATCH 353/545] fixing fuckeries --- libraries/fbx/src/FBXReader_Mesh.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index 19bd99ec5d..72f0fc6f23 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -734,8 +734,7 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { clusterIndices[i] = (uint8_t)(fbxMesh.clusterIndices[i]); } vertBuffer->setSubData(clusterIndicesOffset, clusterIndicesSize, (const gpu::Byte*) clusterIndices.constData()); - } - else { + } else { vertBuffer->setSubData(clusterIndicesOffset, clusterIndicesSize, (const gpu::Byte*) fbxMesh.clusterIndices.constData()); } } @@ -763,15 +762,14 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { bool interleaveNormalsTangents = true; // If has blend shapes allocate and assign buffers for pos and tangents now - hasBlendShapes = true; if (hasBlendShapes) { auto posBuffer = std::make_shared(); posBuffer->setData(positionsSize, (const gpu::Byte*) vertBuffer->getData() + positionsOffset); vertexBufferStream->addBuffer(posBuffer, 0, positionElement.getSize()); - auto tangentBuffer = std::make_shared(); - tangentBuffer->setData(normalsAndTangentsSize, (const gpu::Byte*) vertBuffer->getData() + normalsAndTangentsOffset); - vertexBufferStream->addBuffer(tangentBuffer, 0, normalsAndTangentsStride); + auto normalsAndTangentsBuffer = std::make_shared(); + normalsAndTangentsBuffer->setData(normalsAndTangentsSize, (const gpu::Byte*) vertBuffer->getData() + normalsAndTangentsOffset); + vertexBufferStream->addBuffer(normalsAndTangentsBuffer, 0, normalsAndTangentsStride); // update channels and attribBuffer size accordingly interleavePositions = false; @@ -814,8 +812,7 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { if (texCoords1Size) { vertexFormat->setAttribute(gpu::Stream::TEXCOORD1, attribChannel, texCoordsElement, bufOffset); bufOffset += texCoordsElement.getSize(); - } - else if (texCoordsSize) { + } else if (texCoordsSize) { vertexFormat->setAttribute(gpu::Stream::TEXCOORD1, attribChannel, texCoordsElement, bufOffset - texCoordsElement.getSize()); } if (clusterIndicesSize) { From d9495275cc8ff0dc701486349ecfe1c82cd75b11 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Fri, 7 Sep 2018 11:22:31 -0700 Subject: [PATCH 354/545] adding cancel button and signed in checkbox --- interface/resources/qml/LoginDialog.qml | 1 + .../qml/LoginDialog/LinkAccountBody.qml | 23 ++++++++++++++----- .../resources/qml/windows/ModalFrame.qml | 18 +++++++++++++++ .../resources/qml/windows/ModalWindow.qml | 1 + 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/interface/resources/qml/LoginDialog.qml b/interface/resources/qml/LoginDialog.qml index e21e8b7354..336858502d 100644 --- a/interface/resources/qml/LoginDialog.qml +++ b/interface/resources/qml/LoginDialog.qml @@ -23,6 +23,7 @@ ModalWindow { objectName: "LoginDialog" implicitWidth: 520 implicitHeight: 320 + closeButtonVisible: true destroyOnCloseButton: true destroyOnHidden: true visible: true diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index 2274d88e04..4c9fe6ae94 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -234,6 +234,23 @@ Item { onHeightChanged: d.resize(); onWidthChanged: d.resize(); anchors.horizontalCenter: parent.horizontalCenter + CheckBox { + id: autoLogoutCheckbox; + checked: Settings.getValue("wallet/autoLogout", true); + text: "Keep me signed in" + boxSize: 20; + labelFontSize: 15; + color: hifi.colors.black; + onCheckedChanged: { + Settings.setValue("wallet/autoLogout", !checked); + if (checked) { + Settings.setValue("wallet/savedUsername", ""); + } else { + Settings.setValue("wallet/savedUsername", Account.username); + } + } + } + Button { id: linkAccountButton anchors.verticalCenter: parent.verticalCenter @@ -244,12 +261,6 @@ Item { onClicked: linkAccountBody.login() } - - Button { - anchors.verticalCenter: parent.verticalCenter - text: qsTr("Cancel") - onClicked: root.tryDestroy() - } } Row { diff --git a/interface/resources/qml/windows/ModalFrame.qml b/interface/resources/qml/windows/ModalFrame.qml index 211353b5f3..640069a0b3 100644 --- a/interface/resources/qml/windows/ModalFrame.qml +++ b/interface/resources/qml/windows/ModalFrame.qml @@ -94,5 +94,23 @@ Frame { color: hifi.colors.lightGray } } + + + GlyphButton { + id: closeButton + visible: window.closeButtonVisible + width: 30 + y: -hifi.dimensions.modalDialogTitleHeight + anchors { + top: parent.top + right: parent.right + topMargin: 10 + rightMargin: 10 + } + glyph: hifi.glyphs.close + onClicked: { + window.destroy(); + } + } } } diff --git a/interface/resources/qml/windows/ModalWindow.qml b/interface/resources/qml/windows/ModalWindow.qml index 2d56099051..75f5c2d646 100644 --- a/interface/resources/qml/windows/ModalWindow.qml +++ b/interface/resources/qml/windows/ModalWindow.qml @@ -19,6 +19,7 @@ ScrollingWindow { destroyOnHidden: true frame: ModalFrame { } + property bool closeButtonVisible: false property int colorScheme: hifi.colorSchemes.light property bool draggable: false From db96603cdabc35034aa393ed750952c854f618ce Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Fri, 7 Sep 2018 11:23:58 -0700 Subject: [PATCH 355/545] removing some unused properties --- interface/resources/qml/LoginDialog/LinkAccountBody.qml | 2 -- 1 file changed, 2 deletions(-) diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index 4c9fe6ae94..9bb40fd538 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -21,8 +21,6 @@ Item { height: root.pane.height width: root.pane.width property bool failAfterSignUp: false - property var locale: Qt.locale() - property string dateTimeString function login() { mainTextContainer.visible = false From 1a67176819d5171dba901442d07b7a76b4c2c198 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Fri, 7 Sep 2018 11:29:30 -0700 Subject: [PATCH 356/545] Fix a dangling merge conflict --- libraries/render-utils/src/SoftAttachmentModel.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/render-utils/src/SoftAttachmentModel.cpp b/libraries/render-utils/src/SoftAttachmentModel.cpp index 9ab30c179a..93ce8f595a 100644 --- a/libraries/render-utils/src/SoftAttachmentModel.cpp +++ b/libraries/render-utils/src/SoftAttachmentModel.cpp @@ -79,7 +79,6 @@ void SoftAttachmentModel::updateClusterMatrices(bool triggerBlendshapes) { // post the blender if we're not currently waiting for one to finish auto modelBlender = DependencyManager::get(); if (triggerBlendshapes && modelBlender->shouldComputeBlendshapes() && geometry.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) { - if (_blendedVertexBuffersInitialized && modelBlender->shouldComputeBlendshapes() && geometry.hasBlendedMeshes() && _blendshapeCoefficients != _blendedBlendshapeCoefficients) { _blendedBlendshapeCoefficients = _blendshapeCoefficients; modelBlender->noteRequiresBlend(getThisPointer()); } From 44d36ec622dd0fee044ebecac11d6c387d4721a6 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Fri, 7 Sep 2018 11:31:29 -0700 Subject: [PATCH 357/545] wallet should save username when checked --- interface/resources/qml/LoginDialog/LinkAccountBody.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index 9bb40fd538..ca81a6b870 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -242,9 +242,9 @@ Item { onCheckedChanged: { Settings.setValue("wallet/autoLogout", !checked); if (checked) { - Settings.setValue("wallet/savedUsername", ""); - } else { Settings.setValue("wallet/savedUsername", Account.username); + } else { + Settings.setValue("wallet/savedUsername", ""); } } } From 39041f294281f249386a63096faaff4195659924 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Fri, 7 Sep 2018 11:36:21 -0700 Subject: [PATCH 358/545] fixing username field --- .../resources/qml/LoginDialog/LinkAccountBody.qml | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index ca81a6b870..bc0b8fb2e0 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -242,9 +242,9 @@ Item { onCheckedChanged: { Settings.setValue("wallet/autoLogout", !checked); if (checked) { - Settings.setValue("wallet/savedUsername", Account.username); - } else { Settings.setValue("wallet/savedUsername", ""); + } else { + Settings.setValue("wallet/savedUsername", Account.username); } } } @@ -310,14 +310,6 @@ Item { } usernameField.forceActiveFocus(); - - var data = { - "date": new Date().toLocaleString(), - }; - print(new Date().toLocaleString()); - print(model.sessionId); - - //UserActivityLogger.logAction("login_screen_shown", ) } Connections { From 32e2a244a110a7d16a2afd5e319478d6f0f41ac7 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 7 Sep 2018 11:44:35 -0700 Subject: [PATCH 359/545] detailed profile range for avatar unpacking --- libraries/avatars/src/AvatarHashMap.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index c1246866dc..1383939b8b 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -21,6 +21,7 @@ #include "AvatarLogging.h" #include "AvatarTraits.h" +#include "Profile.h" void AvatarReplicas::addReplica(const QUuid& parentID, AvatarSharedPointer replica) { if (parentID == QUuid()) { @@ -214,6 +215,7 @@ AvatarSharedPointer AvatarHashMap::findAvatar(const QUuid& sessionUUID) const { } void AvatarHashMap::processAvatarDataPacket(QSharedPointer message, SharedNodePointer sendingNode) { + DETAILED_PROFILE_RANGE(network, __FUNCTION__); PerformanceTimer perfTimer("receiveAvatar"); // enumerate over all of the avatars in this packet // only add them if mixerWeakPointer points to something (meaning that mixer is still around) From 9b9785d250620a5982c84a817540c7c4ddf5f95f Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 7 Sep 2018 10:35:41 -0700 Subject: [PATCH 360/545] Fix entity list not handling deleted entities --- scripts/system/html/js/entityList.js | 44 +++++++++++++--------------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/scripts/system/html/js/entityList.js b/scripts/system/html/js/entityList.js index ebf31d5d36..8358ceba4b 100644 --- a/scripts/system/html/js/entityList.js +++ b/scripts/system/html/js/entityList.js @@ -34,9 +34,6 @@ const COMPARE_DESCENDING = function(a, b) { return COMPARE_ASCENDING(b, a); } -//console.log = function() { }; - - // List of all entities let entities = [] @@ -49,7 +46,7 @@ var selectedEntities = []; var currentSortColumn = 'type'; var currentSortOrder = ASCENDING_SORT; -const ENABLE_PROFILING = true; +const ENABLE_PROFILING = false; var profileIndent = ''; const PROFILE = !ENABLE_PROFILING ? function() { } : function(name, fn, args) { console.log("PROFILE-Web " + profileIndent + "(" + name + ") Begin"); @@ -62,10 +59,6 @@ const PROFILE = !ENABLE_PROFILING ? function() { } : function(name, fn, args) { console.log("PROFILE-Web " + profileIndent + "(" + name + ") End " + delta + "ms"); }; -debugPrint = function (message) { - console.log(message); -}; - function loaded() { openEventBridge(function() { elEntityTable = document.getElementById("entity-table"); @@ -127,7 +120,6 @@ function loaded() { function onRowClicked(clickEvent) { let entityID = this.dataset.entityID; - console.log("CLICKED", entityID, this); let selection = [entityID]; if (clickEvent.ctrlKey) { let selectedIndex = selectedEntities.indexOf(entityID); @@ -212,7 +204,6 @@ function loaded() { // Update the entity list with the new set of data sent from edit.js function updateEntityList(entityData) { - console.warn("updating entity list"); const IMAGE_MODEL_NAME = 'default-image-model.fbx'; entities = [] @@ -291,13 +282,11 @@ function loaded() { function refreshEntityList() { PROFILE("refresh-entity-list", function() { - console.warn("refreshing entity list"); PROFILE("filter", function() { let searchTerm = elFilter.value; if (searchTerm === '') { visibleEntities = entities.slice(0); } else { - console.log("Filtering on: ", searchTerm); visibleEntities = entities.filter(function(e) { return e.name.indexOf(searchTerm) > -1 || e.type.indexOf(searchTerm) > -1 @@ -308,7 +297,6 @@ function loaded() { PROFILE("sort", function() { let cmp = currentSortOrder === ASCENDING_SORT ? COMPARE_ASCENDING : COMPARE_DESCENDING; - console.log("Doing sort", currentSortColumn, currentSortOrder); visibleEntities.sort(cmp); }); @@ -322,16 +310,27 @@ function loaded() { } function removeEntities(deletedIDs) { - return; - for (i = 0, length = deletedIDs.length; i < length; i++) { - let id = deletedIDs[i]; - entities[id].el.remove(); - delete entities[id]; + // Loop from the back so we can pop items off while iterating + for (let j = entities.length - 1; j >= 0; --j) { + let id = entities[j]; + for (let i = 0, length = deletedIDs.length; i < length; ++i) { + if (id === deletedIDs[i]) { + entities.splice(j, 1); + entitiesByID[id].el.remove(); + delete entitiesByID[id]; + break; + } + } } + refreshEntities(); } function clearEntities() { - entities = {}; + entities = [] + entitiesByID = {}; + visibleEntities = []; + elEntityTableBody.innerHTML = ''; + refreshFooter(); } @@ -351,14 +350,14 @@ function loaded() { } function setSortColumn(column) { PROFILE("set-sort-column", function() { - if (currentSortColumn == column) { + if (currentSortColumn === column) { currentSortOrder *= -1; } else { elSortOrder[currentSortColumn].innerHTML = ""; currentSortColumn = column; currentSortOrder = ASCENDING_SORT; } - elSortOrder[column].innerHTML = currentSortOrder == ASCENDING_SORT ? ASCENDING_STRING : DESCENDING_STRING; + elSortOrder[column].innerHTML = currentSortOrder === ASCENDING_SORT ? ASCENDING_STRING : DESCENDING_STRING; refreshEntityList(); }); } @@ -485,11 +484,8 @@ function loaded() { elFooter.firstChild.nodeValue = "0 entities found"; } else if (newEntities) { elNoEntitiesMessage.style.display = "none"; - //entityData = newEntities; updateEntityList(newEntities); - //refreshEntityList(); updateSelectedEntities(data.selectedIDs); - //resize(); } }); } else if (data.type === "removeEntities" && data.deletedIDs !== undefined && data.selectedIDs !== undefined) { From 3cc90d3c80f9696276902d97e616cb7ec9596d2a Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 7 Sep 2018 12:07:19 -0700 Subject: [PATCH 361/545] Disable profiling in entityList.js --- scripts/system/libraries/entityList.js | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/scripts/system/libraries/entityList.js b/scripts/system/libraries/entityList.js index 3900260d0c..06255e38ae 100644 --- a/scripts/system/libraries/entityList.js +++ b/scripts/system/libraries/entityList.js @@ -11,8 +11,9 @@ /* global EntityListTool, Tablet, selectionManager, Entities, Camera, MyAvatar, Vec3, Menu, Messages, cameraManager, MENU_EASE_ON_FOCUS, deleteSelectedEntities, toggleSelectedEntitiesLocked, toggleSelectedEntitiesVisible */ +var PROFILING_ENABLED = false; var profileIndent = ''; -PROFILE = function(name, fn, args) { +PROFILE = !PROFILING_ENABLED ? function() { } : function(name, fn, args) { console.log("PROFILE-Script " + profileIndent + "(" + name + ") Begin"); var previousIndent = profileIndent; profileIndent += ' '; @@ -21,7 +22,7 @@ PROFILE = function(name, fn, args) { var delta = Date.now() - before; profileIndent = previousIndent; console.log("PROFILE-Script " + profileIndent + "(" + name + ") End " + delta + "ms"); -} +}; EntityListTool = function(shouldUseEditTabletApp) { var that = {}; @@ -82,7 +83,6 @@ EntityListTool = function(shouldUseEditTabletApp) { PROFILE("Script-JSON.stringify", function() { dataString = JSON.stringify(data); }); - console.log("Length: ", dataString.length, data.type); PROFILE("Script-emitScriptEvent", function() { webView.emitScriptEvent(dataString); if (entityListWindow.window) { @@ -90,7 +90,7 @@ EntityListTool = function(shouldUseEditTabletApp) { } }); } - + that.toggleVisible = function() { that.setVisible(!visible); }; @@ -121,7 +121,7 @@ EntityListTool = function(shouldUseEditTabletApp) { selectedIDs: selectedIDs }); }; - + that.deleteEntities = function (deletedIDs) { emitJSONScriptEvent({ type: "deleted", @@ -150,7 +150,6 @@ EntityListTool = function(shouldUseEditTabletApp) { PROFILE("getProperties", function() { for (var i = 0; i < ids.length; i++) { var id = ids[i]; - //var properties = Entities.getEntityProperties(id); var properties = Entities.getEntityProperties(id, ['name', 'type', 'locked', 'visible', 'renderInfo', 'type', 'modelURL', 'materialURL', 'script']); @@ -168,16 +167,16 @@ EntityListTool = function(shouldUseEditTabletApp) { url: url, locked: properties.locked, visible: properties.visible, - verticesCount: (properties.renderInfo !== undefined ? + verticesCount: (properties.renderInfo !== undefined ? valueIfDefined(properties.renderInfo.verticesCount) : ""), - texturesCount: (properties.renderInfo !== undefined ? + texturesCount: (properties.renderInfo !== undefined ? valueIfDefined(properties.renderInfo.texturesCount) : ""), - texturesSize: (properties.renderInfo !== undefined ? + texturesSize: (properties.renderInfo !== undefined ? valueIfDefined(properties.renderInfo.texturesSize) : ""), - hasTransparent: (properties.renderInfo !== undefined ? + hasTransparent: (properties.renderInfo !== undefined ? valueIfDefined(properties.renderInfo.hasTransparent) : ""), isBaked: properties.type === "Model" ? url.toLowerCase().endsWith(".baked.fbx") : false, - drawCalls: (properties.renderInfo !== undefined ? + drawCalls: (properties.renderInfo !== undefined ? valueIfDefined(properties.renderInfo.drawCalls) : ""), hasScript: properties.script !== "" }); @@ -212,8 +211,7 @@ EntityListTool = function(shouldUseEditTabletApp) { try { data = JSON.parse(data); } catch(e) { - console.log(data); - //print("entityList.js: Error parsing JSON: " + e.name + " data " + data); + print("entityList.js: Error parsing JSON: " + e.name + " data " + data); return; } From d09391faa5f1247c127e554e9e8c8438cdfe5749 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Fri, 7 Sep 2018 12:17:40 -0700 Subject: [PATCH 362/545] Fix invisible error --- interface/src/avatar/MyAvatar.cpp | 1 + .../controllers/controllerModules/teleport.js | 104 +++++------------- 2 files changed, 31 insertions(+), 74 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 9a78f394e1..1a5f8804e4 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -3315,6 +3315,7 @@ QVariantMap MyAvatar::getCollisionCapsule() { capsule["start"] = vec3toVariant(start); capsule["end"] = vec3toVariant(end); capsule["radius"] = QVariant(radius); + capsule["scale"] = QVariant(getModelScale()); return capsule; } diff --git a/scripts/system/controllers/controllerModules/teleport.js b/scripts/system/controllers/controllerModules/teleport.js index 92fc91094d..02b470d332 100644 --- a/scripts/system/controllers/controllerModules/teleport.js +++ b/scripts/system/controllers/controllerModules/teleport.js @@ -22,7 +22,6 @@ Script.include("/~/system/libraries/controllers.js"); (function() { // BEGIN LOCAL_SCOPE var TARGET_MODEL_URL = Script.resolvePath("../../assets/models/teleport-destination.fbx"); - var CANCEL_MODEL_URL = Script.resolvePath("../../assets/models/teleport-cancel.fbx"); var SEAT_MODEL_URL = Script.resolvePath("../../assets/models/teleport-seat.fbx"); var TARGET_MODEL_DIMENSIONS = { @@ -63,28 +62,26 @@ Script.include("/~/system/libraries/controllers.js"); alpha: 1, width: 0.025 }; + var teleportPath = { color: COLORS_TELEPORT_CAN_TELEPORT, alpha: 1, width: 0.025 }; + var seatPath = { color: COLORS_TELEPORT_SEAT, alpha: 1, width: 0.025 }; - var cancelEnd = { - type: "model", - url: CANCEL_MODEL_URL, - dimensions: TARGET_MODEL_DIMENSIONS, - ignorePickIntersection: true - }; + var teleportEnd = { type: "model", url: TARGET_MODEL_URL, dimensions: TARGET_MODEL_DIMENSIONS, ignorePickIntersection: true }; + var seatEnd = { type: "model", url: SEAT_MODEL_URL, @@ -93,19 +90,20 @@ Script.include("/~/system/libraries/controllers.js"); }; var collisionEnd = { - type: "sphere", - dimensions: {x: 0, y: 0, z: 0}, + type: "shape", + shape: "box", + dimensions: TARGET_MODEL_DIMENSIONS, + alpha: 0.0, ignorePickIntersection: true }; - var teleportRenderStates = [{name: "noend", path: cancelPath}, - {name: "cancel", path: cancelPath, end: cancelEnd}, + var teleportRenderStates = [{name: "cancel", path: cancelPath}, {name: "teleport", path: teleportPath, end: teleportEnd}, {name: "seat", path: seatPath, end: seatEnd}, {name: "invisible", end: collisionEnd}]; var DEFAULT_DISTANCE = 8.0; - var teleportDefaultRenderStates = [{name: "noend", distance: DEFAULT_DISTANCE, path: cancelPath}]; + var teleportDefaultRenderStates = [{name: "cancel", distance: DEFAULT_DISTANCE, path: cancelPath}]; var ignoredEntities = []; @@ -117,9 +115,9 @@ Script.include("/~/system/libraries/controllers.js"); var TARGET = { NONE: 'none', // Not currently targetting anything - INVISIBLE: 'invisible', // The current target is an invvsible surface + INVISIBLE: 'invisible', // The current target is an invisible surface INVALID: 'invalid', // The current target is invalid (wall, ceiling, etc.) - CANCEL: 'cancel', // Insufficient space to accommodate the avatar capsule + COLLIDES: 'collides', // Insufficient space to accommodate the avatar capsule SURFACE: 'surface', // The current target is a valid surface SEAT: 'seat' // The current target is a seat }; @@ -205,20 +203,20 @@ Script.include("/~/system/libraries/controllers.js"); this.teleportHandCollisionPick; this.recreateCollisionPicks = function() { - if (_this.teleportHandCollisionPick !== undefined) { Picks.removePick(_this.teleportHandCollisionPick); } if (_this.teleportHeadCollisionPick !== undefined) { Picks.removePick(_this.teleportHeadCollisionPick); } + var capsuleData = MyAvatar.getCollisionCapsule(); var capsuleHeight = Vec3.distance(capsuleData.start, capsuleData.end); - var offset = Vec3.distance(Vec3.sum(capsuleData.start, {x: 0, y: 0.5*capsuleHeight, z: 0}), MyAvatar.position); - var radius = capsuleData.radius; - var height = 2.0 * radius + capsuleHeight; - var scale = height/2.0; - + var scale = capsuleData.scale; + var offset = Vec3.distance(Vec3.sum(capsuleData.start, {x: 0, y: 0.5*capsuleHeight, z: 0}), MyAvatar.position)/scale; + var radius = capsuleData.radius/scale; + var height = 2.0 * radius + capsuleHeight/scale; + _this.teleportHandCollisionPick = Picks.createPick(PickType.Collision, { enabled: true, parentID: Pointers.getPointerProperties(_this.teleportParabolaHandInvisible).renderStates["invisible"].end, @@ -232,7 +230,7 @@ Script.include("/~/system/libraries/controllers.js"); } }, position: { x: 0, y: offset + (height * 0.5), z: 0 }, - threshold: scale * _this.capsuleThreshold + threshold: _this.capsuleThreshold * scale }); _this.teleportHeadCollisionPick = Picks.createPick(PickType.Collision, { @@ -248,7 +246,7 @@ Script.include("/~/system/libraries/controllers.js"); } }, position: { x: 0, y: offset + (height * 0.5), z: 0 }, - threshold: scale * _this.capsuleThreshold + threshold: _this.capsuleThreshold * scale }); } @@ -368,15 +366,15 @@ Script.include("/~/system/libraries/controllers.js"); } else { result = Pointers.getPrevPickResult(_this.teleportParabolaHandVisible); } - teleportLocationType = getTeleportTargetType(result); + teleportLocationType = getTeleportTargetType(result, collisionResult); } if (teleportLocationType === TARGET.NONE) { // Use the cancel default state - this.setTeleportState(mode, "noend", ""); + this.setTeleportState(mode, "cancel", ""); } else if (teleportLocationType === TARGET.INVALID || teleportLocationType === TARGET.INVISIBLE) { - this.setTeleportState(mode, "", "noend"); - } else if (teleportLocationType === TARGET.CANCEL) { + this.setTeleportState(mode, "", "cancel"); + } else if (teleportLocationType === TARGET.COLLIDES) { this.setTeleportState(mode, "cancel", "invisible"); } else if (teleportLocationType === TARGET.SURFACE) { this.setTeleportState(mode, "teleport", "invisible"); @@ -496,6 +494,12 @@ Script.include("/~/system/libraries/controllers.js"); return TARGET.INVALID; } } + + if (collisionResult.collisionRegion != undefined) { + if (collisionResult.intersects) { + return TARGET.COLLIDES; + } + } if (!props.visible) { return TARGET.INVISIBLE; @@ -507,11 +511,6 @@ Script.include("/~/system/libraries/controllers.js"); if (angle > MAX_ANGLE_FROM_UP_TO_TELEPORT) { return TARGET.INVALID; } else { - if (collisionResult.collisionRegion != undefined) { - if (collisionResult.intersects) { - return TARGET.CANCEL; - } - } return TARGET.SURFACE; } } @@ -605,54 +604,11 @@ Script.include("/~/system/libraries/controllers.js"); } }; - // This class execute a function after the param value haven't been set for a certain time - // It's used in this case to recreate the collision picks once when the avatar scale process ends - - var AfterSet = function(time, maxsteps, callback) { - var self = this; - this.time = time; - this.callback = callback; - this.init = false; - this.value = 0; - this.interval; - this.maxsteps = maxsteps; - this.steps = 0; - this.restateValue = function(value) { - if (self.steps++ > self.maxsteps) { - self.callback.call(this, self.value); - self.steps = 0; - } - if (!self.init) { - console.log("Starting apply after"); - } - self.init = true; - self.value = value; - if (self.interval !== undefined) { - Script.clearInterval(self.interval); - } - self.interval = Script.setInterval(function() { - self.callback.call(this, self.value); - self.init = false; - Script.clearInterval(self.interval); - self.interval = undefined; - }, self.time); - } - } - - var afterSet = new AfterSet(100, 30, function(value) { - leftTeleporter.recreateCollisionPicks(); - rightTeleporter.recreateCollisionPicks(); - }); - MyAvatar.onLoadComplete.connect(function () { leftTeleporter.recreateCollisionPicks(); rightTeleporter.recreateCollisionPicks(); }); - MyAvatar.sensorToWorldScaleChanged.connect(function() { - afterSet.restateValue(MyAvatar.getSensorToWorldScale()); - }); - Messages.subscribe('Hifi-Teleport-Disabler'); Messages.subscribe('Hifi-Teleport-Ignore-Add'); Messages.subscribe('Hifi-Teleport-Ignore-Remove'); From 949efff43919c08e3993301493391b69c153f0ad Mon Sep 17 00:00:00 2001 From: Anthony Thibault Date: Fri, 7 Sep 2018 13:21:17 -0700 Subject: [PATCH 363/545] Fix blendshapes playing back in recordings at 2x their proper values --- assignment-client/src/Agent.cpp | 10 ++++++++++ assignment-client/src/avatars/ScriptableAvatar.cpp | 12 ++++++++++++ assignment-client/src/avatars/ScriptableAvatar.h | 9 ++++++++- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 2f03f15da7..b75567e3cb 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -391,8 +391,18 @@ void Agent::executeScript() { if (recordingInterface->getPlayFromCurrentLocation()) { scriptedAvatar->setRecordingBasis(); } + + // these procedural movements are included in the recordings + scriptedAvatar->setHasProceduralEyeFaceMovement(false); + scriptedAvatar->setHasProceduralBlinkFaceMovement(false); + scriptedAvatar->setHasAudioEnabledFaceMovement(false); } else { scriptedAvatar->clearRecordingBasis(); + + // restore procedural blendshape movement + scriptedAvatar->setHasProceduralEyeFaceMovement(true); + scriptedAvatar->setHasProceduralBlinkFaceMovement(true); + scriptedAvatar->setHasAudioEnabledFaceMovement(true); } }); diff --git a/assignment-client/src/avatars/ScriptableAvatar.cpp b/assignment-client/src/avatars/ScriptableAvatar.cpp index 6f04cfa196..7d2b267a05 100644 --- a/assignment-client/src/avatars/ScriptableAvatar.cpp +++ b/assignment-client/src/avatars/ScriptableAvatar.cpp @@ -145,3 +145,15 @@ void ScriptableAvatar::update(float deltatime) { _clientTraitsHandler->sendChangedTraitsToMixer(); } + +void ScriptableAvatar::setHasProceduralBlinkFaceMovement(bool hasProceduralBlinkFaceMovement) { + _headData->setHasProceduralBlinkFaceMovement(hasProceduralBlinkFaceMovement); +} + +void ScriptableAvatar::setHasProceduralEyeFaceMovement(bool hasProceduralEyeFaceMovement) { + _headData->setHasProceduralEyeFaceMovement(hasProceduralEyeFaceMovement); +} + +void ScriptableAvatar::setHasAudioEnabledFaceMovement(bool hasAudioEnabledFaceMovement) { + _headData->setHasAudioEnabledFaceMovement(hasAudioEnabledFaceMovement); +} diff --git a/assignment-client/src/avatars/ScriptableAvatar.h b/assignment-client/src/avatars/ScriptableAvatar.h index 89f9369133..52beba72a1 100644 --- a/assignment-client/src/avatars/ScriptableAvatar.h +++ b/assignment-client/src/avatars/ScriptableAvatar.h @@ -157,9 +157,16 @@ public: virtual QByteArray toByteArrayStateful(AvatarDataDetail dataDetail, bool dropFaceTracking = false) override; + void setHasProceduralBlinkFaceMovement(bool hasProceduralBlinkFaceMovement); + bool getHasProceduralBlinkFaceMovement() const override { return _headData->getHasProceduralBlinkFaceMovement(); } + void setHasProceduralEyeFaceMovement(bool hasProceduralEyeFaceMovement); + bool getHasProceduralEyeFaceMovement() const override { return _headData->getHasProceduralEyeFaceMovement(); } + void setHasAudioEnabledFaceMovement(bool hasAudioEnabledFaceMovement); + bool getHasAudioEnabledFaceMovement() const override { return _headData->getHasAudioEnabledFaceMovement(); } + private slots: void update(float deltatime); - + private: AnimationPointer _animation; AnimationDetails _animationDetails; From adac872a117bb76f6330c1980bde0e7b1b5a112f Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 30 Aug 2018 15:10:05 -0700 Subject: [PATCH 364/545] clear other avatars in agent on avatar mixer disconnect --- interface/src/Application.cpp | 8 -------- interface/src/Application.h | 1 - interface/src/avatar/AvatarManager.h | 2 +- libraries/avatars/src/AvatarHashMap.cpp | 15 +++++++++++++++ libraries/avatars/src/AvatarHashMap.h | 2 ++ 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 40edcdbd76..4c4235a670 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1192,7 +1192,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo connect(&domainHandler, SIGNAL(resetting()), SLOT(resettingDomain())); connect(&domainHandler, SIGNAL(connectedToDomain(QUrl)), SLOT(updateWindowTitle())); connect(&domainHandler, SIGNAL(disconnectedFromDomain()), SLOT(updateWindowTitle())); - connect(&domainHandler, &DomainHandler::disconnectedFromDomain, this, &Application::clearDomainAvatars); connect(&domainHandler, &DomainHandler::disconnectedFromDomain, this, [this]() { getOverlays().deleteOverlay(getTabletScreenID()); getOverlays().deleteOverlay(getTabletHomeButtonID()); @@ -6368,10 +6367,6 @@ void Application::clearDomainOctreeDetails() { getMyAvatar()->setAvatarEntityDataChanged(true); } -void Application::clearDomainAvatars() { - DependencyManager::get()->clearOtherAvatars(); -} - void Application::domainURLChanged(QUrl domainURL) { // disable physics until we have enough information about our new location to not cause craziness. resetPhysicsReadyInformation(); @@ -6459,9 +6454,6 @@ void Application::nodeKilled(SharedNodePointer node) { } else if (node->getType() == NodeType::EntityServer) { // we lost an entity server, clear all of the domain octree details clearDomainOctreeDetails(); - } else if (node->getType() == NodeType::AvatarMixer) { - // our avatar mixer has gone away - clear the hash of avatars - DependencyManager::get()->clearOtherAvatars(); } else if (node->getType() == NodeType::AssetServer) { // asset server going away - check if we have the asset browser showing diff --git a/interface/src/Application.h b/interface/src/Application.h index aa8323cd38..f988795bc6 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -437,7 +437,6 @@ private slots: void onDesktopRootContextCreated(QQmlContext* qmlContext); void showDesktop(); void clearDomainOctreeDetails(); - void clearDomainAvatars(); void onAboutToQuit(); void onPresent(quint32 frameCount); diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index bcdfc064bd..7e1e1f4ff1 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -93,7 +93,7 @@ public: void postUpdate(float deltaTime, const render::ScenePointer& scene); - void clearOtherAvatars(); + void clearOtherAvatars() override; void deleteAllAvatars(); void getObjectsToRemoveFromPhysics(VectorOfMotionStates& motionStates); diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index c1246866dc..0c5ca06989 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -112,6 +112,12 @@ AvatarHashMap::AvatarHashMap() { packetReceiver.registerListener(PacketType::BulkAvatarTraits, this, "processBulkAvatarTraits"); connect(nodeList.data(), &NodeList::uuidChanged, this, &AvatarHashMap::sessionUUIDChanged); + + connect(nodeList.data(), &NodeList::nodeKilled, this, [this](SharedNodePointer killedNode){ + if (killedNode->getType() == NodeType::AvatarMixer) { + clearOtherAvatars(); + } + }); } QVector AvatarHashMap::getAvatarIdentifiers() { @@ -427,3 +433,12 @@ void AvatarHashMap::sessionUUIDChanged(const QUuid& sessionUUID, const QUuid& ol emit avatarSessionChangedEvent(sessionUUID, oldUUID); } +void AvatarHashMap::clearOtherAvatars() { + QWriteLocker locker(&_hashLock); + + AvatarHash::iterator avatarIterator = _avatarHash.begin(); + while (avatarIterator != _avatarHash.end()) { + handleRemovedAvatar(*avatarIterator); + avatarIterator = _avatarHash.erase(avatarIterator); + } +} diff --git a/libraries/avatars/src/AvatarHashMap.h b/libraries/avatars/src/AvatarHashMap.h index 0f847b2a61..70d7f8c04d 100644 --- a/libraries/avatars/src/AvatarHashMap.h +++ b/libraries/avatars/src/AvatarHashMap.h @@ -101,6 +101,8 @@ public: void setReplicaCount(int count); int getReplicaCount() { return _replicas.getReplicaCount(); }; + virtual void clearOtherAvatars(); + signals: /**jsdoc From 9350d6f36e5c82b142619f5ac3e8665d7802e980 Mon Sep 17 00:00:00 2001 From: sam gateau Date: Fri, 7 Sep 2018 15:35:10 -0700 Subject: [PATCH 365/545] removing performance counters --- libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp | 1 - libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp | 5 +---- libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp | 3 --- 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp b/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp index f326ef39b9..8d46b4c6e3 100644 --- a/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp +++ b/libraries/gpu-gl-common/src/gpu/gl/GLBackendInput.cpp @@ -259,7 +259,6 @@ void GLBackend::updateInput() { // Profile the count of buffers to update and use it to short cut the for loop int numInvalids = (int) _input._invalidBuffers.count(); _stats._ISNumInputBufferChanges += numInvalids; - PROFILE_COUNTER_IF_CHANGED(render_gpu, "numInputBuffersbound", int, numInvalids); for (GLuint buffer = 0; buffer < _input._buffers.size(); buffer++, vbo++, offset++, stride++) { if (_input._invalidBuffers.test(buffer)) { diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp index cedb18c87a..c61ffb09e5 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendInput.cpp @@ -80,10 +80,7 @@ void GL41Backend::updateInput() { auto& inputChannels = _input._format->getChannels(); int numInvalids = (int)_input._invalidBuffers.count(); _stats._ISNumInputBufferChanges += numInvalids; - - // Profile the count of buffers to update - PROFILE_COUNTER_IF_CHANGED(render_gpu, "numInputBuffersbound", int, numInvalids); - + GLuint boundVBO = 0; for (auto& channelIt : inputChannels) { const Stream::Format::ChannelMap::value_type::second_type& channel = (channelIt).second; diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp index 4a8bdc43f3..7cd8756ead 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendInput.cpp @@ -36,7 +36,6 @@ void GL45Backend::updateInput() { _input._lastUpdateStereoState = isStereoNow; if (_input._invalidFormat) { - PROFILE_RANGE(render_gpu, "bindInputFormat"); InputStageState::ActivationCache newActivation; // Assign the vertex format required @@ -136,7 +135,6 @@ void GL45Backend::updateInput() { // Profile the count of buffers to update and use it to short cut the for loop int numInvalids = (int) _input._invalidBuffers.count(); _stats._ISNumInputBufferChanges += numInvalids; - PROFILE_COUNTER_IF_CHANGED(render_gpu, "numInputBuffersbound", int, numInvalids); auto numBuffers = _input._buffers.size(); for (GLuint buffer = 0; buffer < numBuffers; buffer++, vbo++, offset++, stride++) { @@ -149,7 +147,6 @@ void GL45Backend::updateInput() { } } - _input._invalidBuffers.reset(); (void)CHECK_GL_ERROR(); } From c2fe2b60b3ee8e04b2b122f903de1b05591185f0 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Fri, 7 Sep 2018 15:49:47 -0700 Subject: [PATCH 366/545] Use std::vector for ignored avatars since the list will be small --- .../src/avatars/AvatarMixerClientData.cpp | 16 +++++++++++++++- .../src/avatars/AvatarMixerClientData.h | 8 ++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixerClientData.cpp b/assignment-client/src/avatars/AvatarMixerClientData.cpp index c54db90f5d..6c01e6e02b 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.cpp +++ b/assignment-client/src/avatars/AvatarMixerClientData.cpp @@ -11,6 +11,7 @@ #include "AvatarMixerClientData.h" +#include #include #include @@ -239,8 +240,21 @@ void AvatarMixerClientData::ignoreOther(const Node* self, const Node* other) { } } +bool AvatarMixerClientData::isRadiusIgnoring(const QUuid& other) const { + return std::find(_radiusIgnoredOthers.cbegin(), _radiusIgnoredOthers.cend(), other) != _radiusIgnoredOthers.cend(); +} + +void AvatarMixerClientData::addToRadiusIgnoringSet(const QUuid& other) { + if (!isRadiusIgnoring(other)) { + _radiusIgnoredOthers.push_back(other); + } +} + void AvatarMixerClientData::removeFromRadiusIgnoringSet(const QUuid& other) { - _radiusIgnoredOthers.erase(other); + auto ignoredOtherIter = std::find(_radiusIgnoredOthers.cbegin(), _radiusIgnoredOthers.cend(), other); + if (ignoredOtherIter != _radiusIgnoredOthers.cend()) { + _radiusIgnoredOthers.erase(ignoredOtherIter); + } } void AvatarMixerClientData::resetSentTraitData(Node::LocalID nodeLocalID) { diff --git a/assignment-client/src/avatars/AvatarMixerClientData.h b/assignment-client/src/avatars/AvatarMixerClientData.h index 64b1ea3edf..d38a90ef1f 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.h +++ b/assignment-client/src/avatars/AvatarMixerClientData.h @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include @@ -91,8 +91,8 @@ public: void loadJSONStats(QJsonObject& jsonObject) const; glm::vec3 getPosition() const { return _avatar ? _avatar->getWorldPosition() : glm::vec3(0); } - bool isRadiusIgnoring(const QUuid& other) const { return _radiusIgnoredOthers.find(other) != _radiusIgnoredOthers.end(); } - void addToRadiusIgnoringSet(const QUuid& other) { _radiusIgnoredOthers.insert(other); } + bool isRadiusIgnoring(const QUuid& other) const; + void addToRadiusIgnoringSet(const QUuid& other); void removeFromRadiusIgnoringSet(const QUuid& other); void ignoreOther(SharedNodePointer self, SharedNodePointer other); void ignoreOther(const Node* self, const Node* other); @@ -167,7 +167,7 @@ private: int _numOutOfOrderSends = 0; SimpleMovingAverage _avgOtherAvatarDataRate; - std::unordered_set _radiusIgnoredOthers; + std::vector _radiusIgnoredOthers; ConicalViewFrustums _currentViewFrustums; int _recentOtherAvatarsInView { 0 }; From 5140999445ffeb87a39e926d50e6c0b2e43df9a9 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 7 Sep 2018 15:57:04 -0700 Subject: [PATCH 367/545] Forcing all the meshes with 3 buffers aka the blendshape layout --- libraries/fbx/src/FBXReader_Mesh.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index 72f0fc6f23..e8b5abcc9c 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -761,6 +761,12 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) { bool interleavePositions = true; bool interleaveNormalsTangents = true; + // TODO: We are using the same vertex format layout for all meshes because this is more efficient + // This work is going into rc73 release which is meant to be used for the SPot500 event and we are picking the format + // that works best for blendshaped and skinned meshes aka the avatars. + // We will improve this technique in a hot fix to 73. + hasBlendShapes = true; + // If has blend shapes allocate and assign buffers for pos and tangents now if (hasBlendShapes) { auto posBuffer = std::make_shared(); From ff645be78ba7b603dbe5919a2619c369ed24f78b Mon Sep 17 00:00:00 2001 From: Anthony Thibault Date: Fri, 7 Sep 2018 17:09:55 -0700 Subject: [PATCH 368/545] Update animations for jump, inAir and less feminine walk cycle --- .../resources/avatar/animations/idle.fbx | Bin 2240928 -> 2228064 bytes .../resources/avatar/animations/jog_bwd.fbx | Bin 0 -> 976816 bytes .../avatar/animations/jump_in_air.fbx | Bin 708768 -> 863840 bytes .../resources/avatar/animations/jump_land.fbx | Bin 927728 -> 923232 bytes .../animations/jump_running_launch_land.fbx | Bin 0 -> 1241936 bytes .../avatar/animations/jump_standing_apex.fbx | Bin 254832 -> 626272 bytes .../avatar/animations/jump_standing_land.fbx | Bin 346176 -> 1025792 bytes .../animations/jump_standing_land_settle.fbx | Bin 0 -> 1531152 bytes .../animations/jump_standing_launch.fbx | Bin 0 -> 837904 bytes .../avatar/animations/jump_takeoff.fbx | Bin 690272 -> 685776 bytes .../resources/avatar/animations/run_bwd.fbx | Bin 0 -> 826448 bytes .../avatar/animations/settle_to_idle.fbx | Bin 1379376 -> 1556080 bytes .../avatar/animations/side_step_left.fbx | Bin 832496 -> 826848 bytes .../resources/avatar/animations/talk.fbx | Bin 5211632 -> 5231552 bytes .../avatar/animations/walk_bwd_fast.fbx | Bin 1042016 -> 1038608 bytes .../resources/avatar/animations/walk_fwd.fbx | Bin 1157312 -> 962416 bytes .../avatar/animations/walk_fwd_fast.fbx | Bin 1008352 -> 909200 bytes .../avatar/animations/walk_short_bwd.fbx | Bin 533008 -> 1214800 bytes .../resources/avatar/avatar-animation.json | 429 +++++++++--------- 19 files changed, 225 insertions(+), 204 deletions(-) create mode 100644 interface/resources/avatar/animations/jog_bwd.fbx create mode 100644 interface/resources/avatar/animations/jump_running_launch_land.fbx create mode 100644 interface/resources/avatar/animations/jump_standing_land_settle.fbx create mode 100644 interface/resources/avatar/animations/jump_standing_launch.fbx create mode 100644 interface/resources/avatar/animations/run_bwd.fbx diff --git a/interface/resources/avatar/animations/idle.fbx b/interface/resources/avatar/animations/idle.fbx index 801237036f517bace469cd732c9613e7adc14549..88c79185a1c5207d9cd176e19b20dad29fc33a22 100644 GIT binary patch delta 381252 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 z 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 G@c#k*?}#!0 delta 391993 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

5MSgD!G6O7o7|I7H|d$)g=^s-J-;@!h!;< zoI$~?$h?GExr}8+=p|&DfS|`gL8dkcULsg^c?AU<&%mK4K2cyk_YzcM(ubSYGax)@ zd%+p2AO;k}h=Lbjr0pfx6-Y186B8c9-~whLJn{xtH&QGo_q;*p2~0a4;uE1~I`4nR zbRznE6RyNC0t-L`M!0-VQcMagB@8}*lG8qLfRKRJypNwWa$_0c^To8mDS*6uPLjD3 z9p{DPI$q)vHD`8TEF;k0=LlA$x*z;(=^T~~IX@79eE}Iqa3>5I!hZiDNFdGp;X51) zmJJ<$z{UusArJA1U^JEgKWv7&w|0bPUZye4;o#i7CUc;b8G;`e0xllRW?(YH+bo z3;}u1KS!l_2*9ll2GhR<_dT9|9A4;S$Vqs(4^f01hX*hw%t?7G6fo8cnqjhs6QOI8 zP%s8?^@K&Qufdg=1po_RgYCc=c5+4#V~HUR1H_yP1H>Ts-+=6qAIl5J8%Qe)L5~x5 zJbYdvSgm?A44!~o90np-xSIM6sKdmEv6Ma#AFhYP$uuqo6B8e)yJ5IE7x^EC1X4Q+4&VQrnhH^Xi#AL{9^w;WZDiCxT%3q( zi@}u`E?~iJ5FRKYcy*is*$L*hg$Dsow;``6gg%lh8lFg2EEx>Zz`r`eN3DTnvb>??G%hg4<(agK!Mo`S=$NWU(iEKnT+t<0Vck#xn9x3>+Ld<6xTU zv3}CT0Y4LBkKuTTPqeqYFy)iS9yvgVn=lU8^!$m#fDa_O0m~xsaC}E%9lsb4kiW%& z>7Ru=W5NS76dr#P9#kQm_~R$(3|Pmd698%TpxJSFAUe_f-aD@2B|cI97EAzR!c0A^ z0uBNLaUzBkRy+F> zqQsLx?`lj#9^wK+&j?WF8P=EdpL;`s|<>YM<6J|h|{ctq}&{2VD$wPc1Grj@$#L#gfIesDKA39+9 zaj-BDsV6Z3oWmGGHUT!yZ^$kMp?~~@JoWfN0UMSMqBLOrZR+vh`3c4p1Sq8&Qh}A@ zgn_`sw(r!neYghmTCM{^upuvff%lyx_U6s<1#p`J*`=Ml#TY#P%m=k+;t(LteEEkA znXm9!A%?ww3w;H_^$Um%D{y;EY&iE7?tJ{z;qWWCRouq(#rV4R6=NJZ^%af`lo@dF zF~Ky#qz!l(z}?VvV4)@*_VoDO+%{amSm4S8OXmjGJ%&usIVl57bYI4QG_m8HhP*OQ zHopY4mT`R7Rls`2mj$RP0L^UU5$wkiGZVo}e4=*Fo(14An;up^2WQ`I7I@fr7whd3 zz(bB@!QPVPz}cW7)?1t$NT>}#kCP3YMQ8sv-s4wtf8Zh}*mCB=)2V~?mnIkZn~($i z?aKMDKRbdj7ZfnJWsz@i4tNvm@x^bT_cu&K9^!J!pHs52FDhr@j+k|QB9zYj4eL9! z{1L&4^B2PTcFdtM*5^5Zh#dL``%IhRVLd-z06fpawBvzZ zent=?CgDyPw@(z<=?ngGd;T+m6R}}r?7!hk%$KnGq4IPD+i|2UL$KrB!*W7Y4glYlffdnE2B0ueejhGiHp8Wg zlPIr-WrL*xP?`eSm7g3tCsOZ&$925KCxY*1D*hn@7Jmm%JLfCl+mZ~HjbQ+c{8<6m zKpdjM0R=WPChD!B!Ps5V$7AOs1cL3^=zqvK5pSP@D=~K^pyLi~Q&z#71jHB2!G~7` za6>BrCpDG-aIy^-Fb@v6s=*@D#WKQB4LT=P9e3g(K2eG9!<6A9?L;yDboD=+!0Pds zG~igbpbEhbpF)^}U;qFkTdDyg$3HKtK7MCxiZPC1WT^&B#|ucV23!jm34rE%`f&{} zL|Az`#bskL7L_M4vYGI%;Wb^>&V-16Pgg)YL z16UkjqNR>AT>)CpkTc3@zLPsH>aFlBhDp9t&k!<85^V3B>W>wBT`j^hV`(pWBj z0AyrYC%o?V0c~iukd|6}-^18U*3-Pj!#~6SM0v z>iAG@DS`=k*o|R@74JTll(lZ)jcYep6xrQ?Tg;&_1s5;@kg^w0VUDE&uNQO&?WUgV)40ECJJF0K$3<5Rg3f9|Sw1A1+|_2>t|^6b(#gjQ>01ptJWl zh}(tZaOdNrVG%B1j)wY)lX;iJ`dB;xe9V}D=l$0tFmWBz2IFGuBrtJz@_2mw1SD^p zI%I+-fgQ~GPze_>=fk@$1Uqth3O@h-ndtE;fMYoY{7jts$IouKfSG8-4BQ*sH!zNF zPJ`Z_)5pDdh)@2UK^~?IPxQ&3Huw!!Vpc!=XAZy$EL}oCIQI06c-pPOv9vG_wBqqZky%R! zDBKh&iX=XQAq}vQ6w3he;xY^w^#_I|qTNB9!Z~&7)FX%^9m!Z2F@-S1Me6JzAdYE# zI>^`=c^>iouuy0YVT6Y`IE2EN5w{UaWDv!DBqRQqIo5>95isF=1WX{N@e0Ea5mxxb zg@j0qg(3u0HH2U&oY+KUBanXyk;f*ah~`MafA>PBq6{>UKocHe;oogUD=t!k3<-U3 zBWHxh4iIvPH*By`d#urTGDyx2$%Ob$1_?DFX%U<>z$P+|0SS#i#^o;L!b57}A_p0e z5JmYJDI#e$U`zqxxQwKMWK#$T3kQjiQg}!oHY8;F7FQFY!VT=4vcuY$VFPv!*?=7@ zE?@_d&IOq!BV`ahT+qj4w_96t>9 zfFFQ`@&m9&egL+~55P)A0N96r!1M$Fn5_T+8@>vIv4{XLB@qDTB?7>*L;%>T5&&a2 z!H$eV6o6e61z=Iq0F3BJ4$!6nFA_eaA}&(qI+#I3h*BZrW#lb9?lv%E0L(PXAaCO$U*1MSUaRC%h#z`|2J%QH zJS6o!B*Y=a$Ou&`BP9`6ErEqf8>|JVd%!~2Jz!zq7`AZp0k9wfEbM3?`EZdz4=|3< zLD%je&l8P40Zl}qaCuyo!k{}yemuklOQ`f7@(yCz4j8-kk2^t@z*w>+Fm}cco&rrf zFa@r5U<&f>z!Z$zfhpkig2Db-(KqY?n1MY2`{4}0h=tt1u+-sQRR0*MfI!;1frX76 zc!`9J3JI9NlD4%%%Htu~yx=9R9|{b8FvC*h?F9_QcmYEMfiOi@fxwU|6h4c`2;n*- z<&a+kVTO+50TD73w2%Uu=#3*DVc}P2N3d3*wMRQL(Z(bOj} zM_)7Gk-xx#DSZZD#-9OLOF9g8Is<@-WB@SR3;-6N0l>`j0hleJ;D?iFe<~Az(PsiM zzdRVME)RgMgY`2g&0J^*v817JT1uwcdc0IVY)fXS4?oCcu*r&loR9>s-w>Xb7M z>ANSI@9<9f>j?9aQqV9nOA1foQwhh}(6N%C%k^Fi81_HZ(CiC?*lrlqf@crCb! zEws-$SZOjttoH)G3d4KFyS^XasN-Ck6dJ<|7d91H3Y%@;TX}CW6F=Yi_Rlk!E#p@1 zrlfJX*D)y}s!{CgTRR4qn!mZADrAEO8ZN&t6OM3lYGQEa6;!AQ{=pOV_D*!DIDd%4 zg4tV_cv00xCm${);#h0&FHm!CQBOe zIuZAULL(vXn+}wk$pNibo+1uf4aKfXseF(B4Gq7hwAKeH{jqL2ui_enmpy}ZV%+l- z-UG#pI^N)ym#Rc`UZC z=FT~??ZwCsQoicd5^y@&v|kB@tgOl$MpjoH;sfSXSf5%9m5JPuQ@VlYwKM(LSWiXw zHp6(YwoH&ihu9eVRzW=XqI$CA)h%V%+V zCX<#>q*!v~nw45~dfu5Rvqwe_LcjL7>@9=iNUy9;xJq~U;N2uW=sB`c>^y2hgHxD@ zwGKoQQD|KG3=8TK-f<-H==ZqO>cm{R7MlL{wxONx9aY0t`3*sH>7rNtH}eAh6j_@n ze|<_xq0%0H=Xaf4>7DAm3rwmGUH>aqTtn8JdtxQZze!jEQeD?U!MR)q|E}dO42`C`QNm`MK zbC~BcklrR2TiQa8le@)^hglf#m&%Wy% z*cQ0zds|Wl<+I`BTlKmk*|r_pGTEBJxl*@F-Y{6%KsQ+R>^84y>gnfVzso<``h_E< z9+xAG9-81dof9?l9I%-j6AcR<^AZ{P-RHi5uWKir{3y2N4Byh$4{y_c^44_zenX)= zRb~MaJtTpJU*+5((|B!!aZSC3v#fO5&1*xo93;J2mr!0TO#GGcYHgJ-V##Y#?z)ZV zrgn{|G$`0+=(Fyp@)KKYOIE5xF7}B|^Zg#3PRg^rQT;%#gzfdlnzb3)r(VhQh_>~a z|CSp~b*C!@-_R)H=+HIWrbME_u&g3~M0%9%Qr-4c%yf?M(NCOW?G}yV--K?Nj(#Cm zKj$oYtFWRbwo4>vo|Y^VG8eeA?R)0PO0~97@RJsJOWUAM1t_72!$LP+IvUlCy~|RH zJ`!VT&nwSV2^?fg#IYfDc=3+G!|kS(kCDw9uj^ z+-?r4-R)ekafuJy3|ZJ?;J={%fx2O9>!ObvQgU3`>I%8gQ5zmp|G9vzu$fAO+6MJM zUMmILs45(fg|ROR;W;)fWX{uFORL4n4(PrX)JWxadHJZR`-93t+pQdvqO&esi+}X+ z=}MQbp+D_)WZQ+_Urf9mLBrdcsIBMY>gSdJ@TKVA+Y+8N-#)3Xxpq3&{z-RjX#d(? zH_PKzE<3~I8Z_&rSV*w8{ns#OVjsW%Y$G|Vm=p^4F!LN)lnt>z)ax*3I9lA?<~r%w z(Cs`@z!-A(^#QSCsMn|hvzHBjYrrhSikE!sY}Lb8EUtUyS@(i=V)U~#gEm|S1Zkp{ zXX!O$Ms0Sj<-(5NX;7SI%qE+sgKz01zFr1_u-ExDPcz)$l~VeKo)nm12U*-3ki~Te z8MityH`sl7)&1mrq*Zvb61T*=*AnP0B|7za!A^Q!Up1oPIhr#D}W=Qb5(ew8hhM zlUbeF{!ZAQ`i~A=3ZTcX}nBy%3e0D&G-B!Zh7S3auqirq-Lh z7!zM9U*%1Sd1(E|JVub_yO{RK>RGoZXB_tkx_*?}U;eDTn{&?Jy*u}g?ZdO* zZGI_}|E=w8PTG8Tmr>p`1tmoNkm{D@Eo#R)rB0?qLVMbP+iBY*jD}2#D(CHEL=4q4 zcQxg9mHRhix!g2O@|j2v&!?1I zw|yd}>)cp=|HnC$k0wC>40^zK9eG;ig*A2itV~t%w)%s`j2ebvmmv)le~m18sM+(E z2uWVb9Pazxeb7_QJDX8zRx9I{5=>&VA)5wS8D6F3sR`)}sMmSV)Fz?~u1=7Z{fUgO zJ$+Ygg#PiLnA5j{S_5ZPECjnQ>9p()ot;571Q!|z$D+%x*IE=vu9JkdP9&;-pOoHX z-k!+gcXtRCJzCs*ShhlT5jE}BfE?;mTL*?CH@+ep+^J~mpadUf=!{Cr?bpTN=} z^y#awoHu?A9;tItDUFMc(;2&Lg3DfHA*|V&?tfV(xac+SHR|n3_XM_}Qq?~g)+K6Z zZ{8tRbNaCGgHxNljhiGqI)4aZKe(()|14-D;H}rMS&)}VQ{liPU=aU#XRTleq z=YL4sS?)ak>N;jqUQ*_cu5TF&t+%Nl3hHiuILjkmz}p1XX;9>aD@Eu%D8I+;dalqWbh%uqrZh@xH#qo``4|&7YZXD&_^bs9$}57h~(M zFjnc(#`IPaI=;W$ykHV>Z9PlrVn?I@IfCzhpL#=Kwq(I!`xckw z#m5USv4l|Fp6z%K&bhlRH#V}|l~-tzKBZAF*hHNjxEmsHn<hDP6JFG{A_j8y;Fdr9(=9c3rqmoBBmjX;^hc~r9u`QptE z_`)97i@C60LiM?6-g!vhuokJtevaq@M03VZS>#RG%cSLR{@%nH?@TTPml&N258@K} zLC;S}`?S*JfhuPNonjZe8ikS*1r6g`6vacqB<~{PVve-2%mw3FH^y-RnGLDgt%{X_ zycM^*oZ-q*EZJFC*&fL(CZdk^B>5!qnYKJgEN%^v@aUs9#<<(UZ3}!@+=tgc8i^%% zq$B6G<~GJg26I;juTG8&r%pERIZ;&a?+2a_gW*o@NO4wDVam1yrQA^ zl@zv@YEh3(Jc=kikJQA6#H9$xT<+qmNI(QZv&Ii{pa0w(_?}U>Nu!!2ApIHF(a!UE z%TM<4gCQy^)G0~-UzPepl+@Lpb|dZ61!-*ejd5ciZdT?F9)ypgglMf}&){cg<@)hi zeGTvH(j!K(4v<>)5=`zApsl^avRZuD2KfDu=p3IAHMHDek7(D}#5S+qupYrycgVGb zZ0SBp%}8I@L8+_mBhN2qNUT!tcu?r9W;XAQMfdBkqIP~{pIu3tVG(;i&ROKrak_tb zOj*xuhGD&&#HM<>H7;!1g_!<#H&J3?d{d-YV*_+oZo`fHr|~2f4m0y;W5a$vw6x6gEcvg=t+?$ICWHm+)y!<%U_eGR?fz zQ?aAcbh_ljfvl^mVW#3amRdMZBjWHzf7Pr7Rcy$4_^>rViG0@$sS4TnyO&?0)z!Q= z@`g+!c1Vj*Ujh!sjyw)~Wzu*&zbPj4@#AH%Tp>d7-#cXPn@xLBNjWLe|7TyWU#b=1 zVz^^pB&JWA$_UkHTgZ?V39H3v{*0qdlx}nJ)`7FNe(R{N;oW9^Rf!mUUFPz`MEb z#b>kcx3{@nXl{G0fvDe(Y1E0D#(h+rJND)Na_C;sh~<^`tvYR*c{y`|N(MuBw2;A% z8=eCLh@uz0_}i*UB>NVQI2%kEW2vlprYj2psIgnLVPi2eo`(V4yJls|6K7~UQl_t5@mnL*1aah)c8sfogR#C;J5Hi zMtR<%#g|-4K)RKE^=;)D^t;z7`wIJf2CZ|i|>C_IaHKaD~qDnyOSdpzyD>umjoDvpwwa8Kp?YEblW zju14f^NnO{&?@1PT=h=D_vfhAxPmjAItfAJQ61r{EQW;4k2NbFMGj?$a_N8cwC_=A zL35a2$%uVR5Fl&iy--qgbazfXv3PQ%#(DU~rG7Wk_U3!H_cc*#KQuwQdhY0vm{1W_n@7w3FWeDXrQ5%(H>~JoIf8fc42=)>mTWds1s0Zi|L?h` z_-~LZYKCD`Ma@2tDn9N5sbbGCoGR)~fK>4bNEHo0s(45LCKdjvr&b>?e7=T*_u2c~ zcC>d_afpIbfJAD^lXnGkjFnynlP95w>EQpNlbme z%B(q=npkHS@lpHBLW9TfaQpOfO8>hH2OC1)T!o8zzxagx3jD<+kn=)YV1|$R<-RY| zc~m}l~KmnbUWMU%f9%Vi+lSnF0X>G z=zoffkO}tRpuE5GddE2C%|JN+r^IEiFE!q%{5sm3Jo$1mXoA7ZZsE_<>1IjGH6NAT z(7(mzJp2k#cgp^`F^8S5?B%vijxl5I%bt!n1N;UW%S!hnS@dULOx}rONGHDaIP{6q zTChm|inT)9)T1dqN3opy0b9hIMKgoJ9xq!iGW|@PxCn!o{GLLEioxz$}P`l=oaN1?{ZZ}XZW1G<44lO z7~HHguBpH$qn|COd+lr}o1n?P5C$rvdmWpNsL=E-7W$rrN}^ljf99m4DQp_X_l5&? zqB}fWd~fCw;U$;8k?rYWZgJpCo&ETeQ2Lv68VJ!f6SCEqO%a@2~8i?=4)Jlgrzu++*D!uk4diO`xPcW*RH z+EbJ}j;y|7}up7g}JuwZw(7WD_Yfs3RCj~=r#f2mIkx%8Ovt4W*=o}=Ma zW*(iu7kwW@lJMWt=>*ar;mW>ewX?jB41nH+#*d ze^>R%OY&4>hH5^B>()aT&2)U}^d-&>RhZE0qTIHBT#_YId%HIEl!1ry!PCGsldr*p z{>}YpJ;fd_)JQnqdfTkMNMz%VpL*N=dAWB{_-o2~XTCp2-WwZGYT%SjiC>#;A&@U# zWMV4`p5hQ3W5du0M>ik_LKf z6(p$Vp{K_>N|8T<3~YHBYMb#864@^9;hdhO`i&J1IEjR~waz$v;s~x1T&d?qjaTb9 zqh8mwglB#&8)6{Hn)Vh`V;XvtL7E+oBPtg%_ED}Ymke4JOLlmDMj04 z6jQJJsT^2dU=#gtWsBivYV7!a4WUIj!!6ThZI#wORD?}5s-DVofG}=ygOt!2(m&GAnPL+0k^G?4`PR@-x*Z9>{3ktIC8*$n^F{0E>W5-dzAyvr5 zxnoZd5VXvn#o;~fSLML|Do2l6i+b{M(+x;t_Q+FDW-WF$ZdPhmJiuwRuBoYM-Z2s9 zbBp?;t(EMfqo>O&-t7`7Suds*mYmrKSN2;9XpPEOFYG_~MEpXhJs|lH(^$Dmz<9}; zqTYrg6*I#x!aecGYO5vk>H_(QvAa(7lU>9VqWRQSL8A7DKldTx+{B}+Iu51tZ{+fy zY~vMu%ptB2p2Z(BGA3xqeBv7`f8=k~-Xi#VVZak2)7bp#-@HC=irOfV66=@2{hRf| zYp}wAhA^&7e|G+;wO{hPiNhX+M}EI|^TTa_ zeYxmmCM8lu7<(X0ztU^zYrL&n)#)lT7-4>9Bb_nGWNurDFEq`VajTbWuFieH+_|DW z>-}$Nl9h(}uLHBe!WioG-fq*_Gs9bHg_6_aWoJk5Co^yD1gb5xe{a?a+*F(7{$93{ za<;0G&GWaRm}A`8xQ_SF><;RGTzNOKJ2<--@I0=$iF2#3N<8clWbicEHv%y{m`k-OuIWlQj|t`!C#>_8V&GZ2!C?)+<35>nH`A9mv<~=>}Hx z>H8Epc&?G>Hm>|aIU;(=9@N}Zx!*6#MVUbJr)9$B!MilO!%o-Uib#6)UV#uR?NE-R z^-E3}iR1Hl4LiE#`yp+*VK>S`~`rL3#eKc3Yb)!}Lf7ib5#kpA|QXesqy9t4+Gs$^GVH`)*HodwhU2XOX31 z#qjpVUMkdjF<7HOJ-{RWz45R11TE+%s!&cuHJ5Gqi_dsN*y1?z?EBTgqR*?5EIi{E zdw9lFIIPAhqz;ch*xZ(xh;@qhS90Qg`FXGOe&yEOLbCJ7)vpzEigxJE9dq)=GXffW z2!6s_{;dh_DBCB4zD3KP2=|daD?NiFHUnSDVcy>$bP7RL2S{qni*3VTR&B@i^G5F-+${X@atwDY{D4!8zhXWzd^!C zy#l{(zOw>eH+!yt*Ud#M;C1u#3V7Wtiv!8g;WFZ{x?#bTR{@yGDgbN!3&4M+dYjlZXr7 zyMmb*?e!0@J`%7_ok<*~^xg5jqimY09^wAs3^^UDdiHtZ-i@1gI;K-(QBhyE_wJ#L zF0CiONO&v5MB`r41qmrN*vnTvuJ@e$u_Qt_pN?Xl`=ecd_j7Qs&BI`w9|IG-vwkuc zbu7KUN1P9KK4*w8BmMU3t5eFNeT9m`rHeOtW z*c?peRVXa7^O7%jlVt`3e&?zCbBk&%+U`vFFWsW~ZDxI48Lu@G9*KvjanDk`(u~$K zwD&djP>-udh8{(Wh>X|2<`Vl6>s3G-{55CnFFCEAqOn)@ieuwQIbO$_+jiOvj<%9i zeG=PI)u(&Is|%>tbxf|Bas323wP$vjZro(zUiHif9=3XrF;Al>T<10V{nbSc3L&=w z7NbZcz5PBp%Tl@W_6KtRO3&Xh1Qb_(gd)Yy_D7=5PYe&5mCT3G=7i;`2w8+=i zGWhfJM^JLpuNEGMi&Q^rxW^lPFTnl4?p&)(ut_?_*&31#<_hu^Xqr>|bA!QfAAQUk z&E$>kkJ>ItdEFTK?P1d*lHK*1>^-zxay`Re3U{2ke5T9oIj);7^aDojj!EdM9 z;`dC+d8;4B;t2Hxi!o|@568$yN8Ep%!ZQ6h?k9oC0eaTvp~db z^MH%j#h$1x(eTFhTm0yosT9tw!9)IJ89!KRr<&D+Wu{w6((BiH)bWPHwmT*mE5AB* zw+wy#D30Rry`eU%nduJtV_anN^hSbh0gG#d!n8?dpMKohOM}c) zeKu_E-#P^?HSnKbPw@X-!2Wfk`zi13)wq#JzvoNJ{NJiPH&!U7A?pPs59*obJ00rEHHB-MRk&4h?}UYnGTsDStE-e#kk=l} z=jc`@sDAq6+^-+*%{uOKxpoTIZ*=I$y>JLNyq<(;`({Z8?U^aS9pK@A7l;d1x zipON1Gz&gG zGMkooqQ0R5vvT``56^Xl&?5^pq9-+m?zB6Jm)Wm`>!-Om}}ZB2bYi*9^IKQTXb zakX4NZ)|AFE~h-EJ*<3!dY;^fHF&L_Y3N8pTE4pWkaSSDYEx1;=kDjqWOP~ZuD?|C zgWQBN)YXRIM?x~zk!tTB-x421Y1}49w+Hq1ze(&IC3GU#tPT$gNcJ3{Bo`}M*9aCU zVDsU5QChP}BR|GhV!3^A0oARsIPJdfX}}zj9JoLpDns5p$rq*EvUP5jy6j5<- zy!Vq7mH&k`YKy0gpJ_#2*N?Pdps?~;X6f2~{o}t?99A_nYh|bD*2hkbn&&u<-gjoV zqs;j0%xd)e3Qe!0UB!&yetGCpY4Bm@V6jnOb$nn$%DP)cp##$lQ?ETmTUqO@P?Zb8 zgz@78(`*6@!9>%0f>M0F6j7*lt1?4#%B{lNkQuGC-L#_fjdLqL_T`ayBfr}l+^CsL z0!P)pZ_xj-&{D6tI=9w{imM+Tt!U~ATv(A(s2CbetE72k=kW?1=T$mlRqffh!#Xl& zYF05>W7)s7XehQ5v0=N>`q{R!-|9D7RFz<*xPnS#@Y~pjM=~0{Nj`z7(wova=})iB zp=d8;rA|5*-ODdKWT-J#@U(WoHQ3ZWx1Scd75QN4dhPVCzkF=&(R{Wu`XMvta3y)IgaA#BM`%s*{}j-2GV=`K6jzK+@}PI6{hA9S6q zvD0;C%d#1M?dkt`4%cGNBVjnqwYc2p4NBApZBg=Bz`V@eX#UyZqqQ=B-8P?8f(pcn zwVl_>j!1N^d$DJT51O;Sub8^})ss3~=S5DvEDLd4>V+qw%MII$<+|fxUHnytJq_bp z=_Dq})hne^XpgYcdj^~u2HY#9IGJVSGEMe%Tii3kD^Rg|W*T?fmT1It+}z7JxKQpY z@(DtV45W2AuP|wyDIG374h~dBj?0A1#KFaU{~WBt-3Do;`Y;-2H8Bah{8^^E0v=J?_8}7|%+3 zBktoe-aB@~GG?e7|FnR@ye$Q;+*tv3mFqXJUnUHETf$y)?!(y2SG~%DSZ5vXvWh)6=!&ilbgzjw&|8DAN>S#h89UKXmw_Xs_K!s;gO=eaR zw7t$E)2Ti>PcgY=Y@ANPLh&qS+v1Xp^$FK-$I#6 zk`21;z8Zop*_U|*y;WbW3G}j7tQxytEo3e?`Hb?EJj_RbpB)zROy}DOku?t8)*9v1 zTjuVv|E9QT;Wj9|XkiyhCxxPPB%Pdg|IV!z+{W&X z!df$^CylBk$IIF@#m1-FCG5)LY~p^=ZccAc-?|um^!vKxP?sqFX3`*P$aHp0d{u5x zt_4~UU&zciL*HULFl8bzE_xQrEoC4^61o(7YS3xjHB#UHXxbA$VNniUQF_|;&@fLm zcXUK0>wMnoQZ^2A^%?1*4V5%|!N5l5FEKY3Z+* za*tk{@$_eWCZF6(VD^57YFRXOISM_uwqIf3agC=pmQIt{*!}2?!NhmQio`tJW!D0{ ztlw?EY9p;)$+DpVy65z(?TOCBCy+O9+_IXuRJWPH+TthbS+^&jkX^u0%v!&M=`-jRNbs! zKqt};{YiC-C(!Nn!CTbU(U@;Kqur6n5&b8ca!DTI7v1YpZ#JYe27Gs06aA~!w?DSF zuS!Ku$|y++$u`zdEj-g@ltt63i}~(bFxKQI{7$RM>GJ1V3>eagi)U)O zIDJEA<9v3K(Y<$+hdqwGak~ze7k3+|`}b1sPC{P{(F&#uSic^3B_%nrShp6Q{-oso-~Wk|L*F{E)I zxo>8yOM)dgO_Gr^YKo@+;@6JfJ2~rL5PN4=j1T-hGy2@e_%e$s+}_s&Hg9MQhswDt zNGA6ErP`6-M*ynul}y zP^x>2biMgt3;jOSIilxQk#yo{VU}a$q-(27>8Z)#gPon&7pOMG!TIuS+R2SP?ix!a ztD-BqIL!xcB8xqNeUjq^U+(_7md#Qows*chRm{-a(0bWt+VyIlnWLF!n49~N5kvj# zb3=l@v$JYh@1Nx-tgBU^xntJ$VpHO0b#+9xN_peZ*)3{U4l5oTTZA2`YI)$qrtee~ zNt6?>71hz$dMKV2;mtZ?tNMm3eS-`aDm_5jBQn@P(6zO}-lbE?K-5K(!BLl&21H#% zAp@iqhG9lu>7GI`<=ASx&OnsAE}rtZIZ4~ z$2|#xA1gANN9T|kc53+pZ2^Kq_~@NHLCXY!bO$cyOI%F}Z9Y3RBxHq8b9X;T|E-~T zWk#3p%8ydmE_Cl+^A#L$IcwEI*Neif95_#?Qyv?BC`g^cWJ>=u?4{#~$jxqL6RJY; zRGom2yW!5#R(Opn%>GYY1HCiS0X(tPtw^$n`U= z*rYQZ195y%L^Ur2i%vxmd!c ztK1ns@L(|Zn%5d<3FV@K(2~^s;`g_tKNh_E_EzaFy%M8DMRcubzi@h-{F4zXnS@=f zMEOMqw)g}!E#1COlh(W1QsUQ)gDAi7p7k@zYUQMnN2z6ZM>>pdN?pBN+PJVT@Mob_ z=51e0TInC5_mVB$)h=q*)#8NdCY-<7nW$bF*j|bI5adv^_jbCdbJlO3nys7np3jfr ziZ?WS@`eSZiCpfd9J7)*y;3$dCBLeXm;{ z3>V5i)n0jm5}EpH@bsCs{9h3^4T-DDd7YINW4Lz(v?sp^kuSeCSaf^uQ?YyY77`|nHVn0~XPw3G>0cFQ6!rNlgWpX=pX z=lI}eU)REV-X|5y52G6~DsF2CQW-G~7rObzxV!SVeyOf&LS1^!c(=lIy802)I?8R@ zR&IPQ`MTlT2In72c582%oZZy;-cj3Z{rcAKt1>?RE*~7^fL+Lxu2a1CyiHf~7r7Wa zmXEJ?RT#bT60ELX4*%{Gf^rh@wjIKWq%$0oNeq+Z5_Kpgu~p)@vD{BA_H0WoWq^Dy z8S&GkAGhz5<^^2^GuLIZ?MP+Yxftqa1AF6rltKEbWRqEAg!PgU93>I{A%oQPV-}pQ zVU$Eis7+4NGQb(#@z0?Ux@=IH8!j`HO@T)U{UyRBNBKSCxF&UtpZx8)p&Qe- zedD|YCee8>!fY5iQ%(wLU#vN$Y&ST58RxbIFx8){8hzwY=@C{I4tYKz-=7+x zvxS5a%TXZ#&3Dc>_BHENEAl)auirdaeeIUj7(1R%@pp58MCs3p_iTpV>A}x>)w(sV zf(fQ7l0*6r0{^18?MDL2<&($WwS}3K$BE}eZav=4pJJ$w9dSdB2wx$fMa#MveqUEiYTu3>SSG_^~(xA`!5mgbqedbF+}s*c5|Zvl67#PZbtxH|8k zrnat)OPAgW9i{hP1%e_7QbnXUY0`Ud2^|G#B1ELAh={ZR(t8u6N|7dzgepA{AOr|} z^WHFX?|lDfetVshnP)v`ueJ78E1HfyxenVU%(n?4z7o|Uw-P{t2HlS}K%FmWRVM2Q z_h$%uBdQa+@LqiMMLfY*nNXz$-4Ti90UP&*-P@=>PucVcc}KF)XyVds!{>qs&a1Xh zs^UGd?aFUnlk*;@%hbm97ujFGgO-TG5+g*Uf=Mgt!2aG-?YiPD7E-amAl&_esx%F&xx| zc4EHzm@5)^r>sQ^*sfjm?+W#T64__F#Y>$B*`(`YvVOxpV7=W0#&!lDMNCI+k50h) z0=OcrObL9vJ)?IF%MoUN;>d=t1k65KZ-sU@z_o-1(Dqv)1I%};o4oiVD-*{hPFfp{ zz@N+13(rtSj@h4RLBLq?>~8r40sHI$`=-VY=3t54xO!Tu&3KGuoM02Sg$yM3hMXCtj)>hFfR_)+AUR8)HieP@Q3x;jRP`*OyTnB;dM`f;{v~A1cfo%j zto2mnAnT`}%mgT?LWF%d*sYVUEekFLNKNn;?UN2;qe^C(*|>gtsN9^glc{Fk=qP^wow6a4TUL*Lu>C} zyD3Fp@rWczUR!;G_*N!%qU+1UimF~gwLpGfI3ry=<&Jm_rMG4!cERJ zkhX9lR)_&Lp(4Jsz)dwJ`d zCsZUb7a;s+>KmU^;s)sXFR)br2b>bP0p1tC0Y;180KbXf0N2F-0pin2KxozpmHv19 z_dnI1|MVIKO5kv>C2nvSxf`64{0+`g{svbdkBe_e{w6*ZZ5;5I_rLLpDd2#b3OB%7 zRUD91R~@&F0LFDM`QJ3UW0a>!*-4P!teA>7OYyC1HW;WTxRHE^> zo7+m~9n0MTMSfx9FT-`8Qw3g_-ka8`?>GKx^PRNyXEt5UpHAdC!kKkar;b2%`h%Q$ zKn`kJSu`DH@s0VeR~yA-|2;&w6DAM-E1vIZD8<s$g31gy8N<96ub&U zQI36{T)be-a-j6#_LmDW@Go~;k+Lmqw}*xtHr1W#MdQg^g)J}HlTnYG6Afd(ugW@R zY3$oiFjR3F)M#4!GlmE zSo)=ZSJ%x!&9)(J6un#LuB0;67se`@noRrHxvUcWwEo<1a=^x2diHTt?z{w>Q=Z3b zr^QMS=SHzWXGnGVFxkqFl7e29tqIo>FA*~3xm<~0X-_Ru8EELs+_~EP?-C17`g?9q zwq`xhspAXW+Gbopa2EqA1g066wCadfr#&P{WXLtY3y42(&*5L(F?E2n;>iZ2{yKY` z@cC>MeD-sU)tLKvPf?tdfXnxV2>7OEhbx^gtr2swZGtwh-Rs`V0p6xI#bo|JfrO<_ z>TVKTNm_MAFA7o``iyCY$nLzMk8P|aH1N@xa21TzO1iyD&+SX5Ay^?6_t8v9alL;o zsP#6+i^!Zcge==$>515Cub3c#E`%d)snsdc9?Yfw^(WrTyxzN86g}yWuby}zyVXvW zGqP6kbvyT5IcsA!JG{P9*WCA%Bv%qk%+RP(?|RD=yz%XB|9v99V~&OTHH1+s4W0q& zbDrA6B5J*?kX@1%Va|^dJOsyWB%f0G`Xp?Q<&2&{*!J^7jv9cU8zHsif!05>qqdYH#eljX#~ z?#`>Hlz#qfuHUzrOtu@R%3YS6c9b;^M1XX~bu>f(#yh|-v8X&bKS(Q?5t!BCULSLK z%4oMm*N^0W_DHvoxJ@Oy{7j+`%2E`|A?Q_bkTZqB1s}Y**WS7{mv~?%P|wumlSE2- zMw|d`tV+Dv$bk0=_g^20A28AqW>H#143ynZ$|YkANV4bC7y1Uo>77pw#rkrVzwh^L zsEA+mak2LdBBrWZH($0OPT%a;J{8x9^yDO@od4A}+`IZlFH%?~M&ZW*0(ErT0h z=*W~VT+Ynw`C21;h4b|&aj(Iv6cKdP;mge!km4urIpWkHE5sjXyew1WK*73S=Fai@ zF&?yhGrjmTW^uQ@&W_6;b{aAMROm>W=hM7h&V=|)qEz9NTYS>^=tz?Hks}r9>Z#Sz7 zZ%CKtaF=OWnMpweZC*e+K@#8*yTWwz<^{GOpriBP0Cn-LtgMXE%4N>OU^@S7yz?3> z=lO@6q~e@aT*s_?{Pc4V_@a=v+fI)nE@;dvdTG_#ewNim(djPg%vWKJr&1hhpUn}u znnr0I;LWo5xslGGaOBWO#JtG6k>O;hkQ$*araR}CN!oV3;MBxjZ^M6y^^lE%g8`cF z@;o@I=@z=y#dhVumi3b3XOVb|=k4VAW}GDBP=ll(POijK3Dw(RJGyeXO~f07m9t%s z{ZEAN2U%7oM&2F>%j%sw+9m2YDe^-A)YK52HBvTNr&f zM$L)^pAGbPYl}F-4W5 z(F9Xuh=n8fxe4&`y$aAF?e2*s2MpHwhxheO#t)-TWiPqwUD zop(h_o}zK>b?}oUVt8Qlw5@s3=KigND{r32>u0>4r*2@fMWcLTkHA`RA0gNM!f7O> z3eA<6==MA{I;76lXn3dGwzjjPLbvbi_(U18>7)J}bE5AX9ILPhdck2G1WOh#BsAl7 z?@64Oc^*Py6&gfyVbs5^H284LFlG-XMJ?y7c5kN}p$Pprpk!pVd=~}k;z#Eu|3J1 zwoAAb@PY3v@?O)~D@ISB?yK$1;j68@U+E_n9gitjjcX$^mGcT?116rYb@pINOgi&Vp`8n3HhFH#Rt6-Rykc^YTilCQO(FL zFue)1H%DjA`|UxIkx%el>c6*RDFfuY3RwAl?Hv%;rvtL(1=0vmt?e9%*^AKzzy`@WsSswpfY*i48 zX{GG2^k)IR`xHBH$}^ngxXhJ}G3mLm_;ZM#AB9xeH5x=O!TnR+5oa4akwC~xFh&K4 z6}WiSqAU0VX0<{#E-Vw$FZZG*xVIwL@W$s1!&~QzJ}DS#Vw)DWpof$# z_H#7N9YD2%J-yS?4ZvNB)weUH%|pPM~|w%${Kl@I)*UoZ&2gM}ZuH5wehr zj|?QasMGkEvNJCV$JE{*I-~`@!5cAK_<8kJU?of^N_af0$Wx^2j34{Zck75fw11ot zS+OX8_Gm?Q4lRXh-P%n*5-(IsxY+cWH+1EY(1tvJLuiCwV1aXpl2QLU#5dYFhxkqV z#vuX>ZyaL1F;0r(aSk!$#v!JvF$A-dAeG0fR2G#&UKyEJ)|zj{TtszfR@Y}I71~;* z>yE6iO+zc+CfyZVn4p-F(e;}s7v&x8HJK#fb_+A8{8(_b`_gO&9NM{D+1UJ+Ln-zX zb_q%D^9a9_80J+GKZLsXD45~-5@J{zB9i%2m3k^Z>m^uU_rb0SQPTzZfk`R;s&2aD zrRNBhcC zR9h1EW`v`{^~1;;dCUl}h$Hz>VBP~ZRNwaweGU6m@Wz_40B=-1i-poVqrjHvoO$xE zdi|wQNoU^$6AhKm&v?h^egUjT{uZ&zknPiFNRPi=++fQTUCh8Y+@8=v2fBtN%2&Rc z=H3ippCrwVtqY{^o4`KNj>uFyAfj?=gpbt?gccs%QqkwL6UKtNRFNDALS}bYuA0?U`t%5GrF?%?1InMoI7o#Ki zs>nVVR_qyD{z5FbvLdWH*^9Q&xue^kDSRPkkHamg-KVvKXfTiEVxMC(dUqh}{)~CDPAcl& zYPFVOPoTE(Xo>p-?@mh) zBlFjP*yKk~8Oy0$T_`!hGCQ@8g6qp)<=X8&U)tsjMyI{!7&(KSsCv9m8e(l&>lb4h z5p&7hXY|b4vteSe9rhpHo=Y4P=5K8Nc_q?5c4lQVa)_aqzxtM>Kltb!VwW^{Bs6(x z2#nxP*+NV>a=y59j@<(}1iqO6SQRR@Y!ykhl~A2gu#^6|?@60sa$<=n=Y}$U#+yhA zaxX?#!N-p-s-BHlMv_^^Y-Z+VB{ln8Yow1;&gEC!s%|5zo8(mIbB!)I6H4r{gjeoH zyA9}87=}^8Ht^ovk8|1+dby-DeU2!<#v=&}C#X3#{?EQC=|c;gKuP~|j1-s;*8o53 z_UxYq_(y(mG!;J>ohI&QsL&069SMC#wN8#`+jjov;aQ_uw zgJW6WJsktG+QAt-76zK2N4%PnI_xFuQx{;hK>^Ta*nYr40BkrSjFN(a;>RP*w@10J zr7`H)Yw#8Hb9=|pBWv(^9Q%HgJY_KXz9?X3_*oQ5>u6du#HA=9Z#JllafihIfZWU; z<-~GnN8f{CtX5uE|8pGJyK?zbYeCu`R1ZI|xi&eD3{)A)tqLt**?mu;OI zt#^TY{GlOFPWQM+0pfVKg$@zkk9{{Ac1O)u^PcA%D|O0%gdG^0t8T8gSuJ|jo9t_@ za`jpx;i?Drr61E=n6%b|amX2Yh@E-phJ2mqeioN1ta$3JvJ01`2iA8}1b>^SoYiXR zmfI8%XQ(=u2qSO0Jd-@4qz>rxv{9uA5mAUP4^Krz@ZUwAQuafm-Vvf&<+bgdvxM44 zwUZ9x0FwwGa`0K(=$qL)oD9LtRYjrnGm7oeGT20TbnFX7H5EY4feNv*Xlk4x+wk*4 zj1gr$yiL`&UK{|d?ii@1>Fl^i4`j_EDjjJj7=K39lN+($o2CET7yencNm7>X%C!+- zy#?f8LId)I{Q#!{o_B1;j|HXz;3Y--iTx*mOp!%%;NUg;PJ`gaE<9E_>oBZjKHEC} ztk6I=z-q*P{rLHus5}wS@j}E}Zu(XcbMMK|$o)Ho&#rFmv!E!J`8X=+_F)o@V(>Ye z0C-A-n7zcN?R12_86hlWD{**QM$(q6hPk0b3IKX{H^#6?IVs$6IhQo0sQT)+kjiyL z?Gy8S@PQa2D&KM`;XK9t51c^37=aoq^!;v2W~T4ZCYrKZA4Hwm>7Gw|p3W(mP_5{D z{m_%jp{+@6tDNxo!0a7i3Ti54S-rhrlnue*5%(PO$kE)oS}X4ZO<`kRcRIoqJDAWD zs;5oA@{=evx0dH!KDG9#3Ea6m$9Y5bOK2+cQ5MC==4u=fk?V`84*BNu&f?>ZAd_hbPkJ>?*C@&rRP0?`Z)=)3sc7TgSiCK^n?I~V3Eyq`+@Ru__-&M%2uvK zn?DbXq>kYdB>7G13F)R)hqv&e>=4=5pF{E8N)GafeVN1*d1#>>Oth~uO}Xa{Z5tPU zl)xPjj}J3eNDJLnO>oe?K+A#5L4r*cN9t&)7N!V2G||_eNL~w=AA-gVbbHU5YU`mJ zpMA=FJNw74^M-<)dqVFo1ejZWOnOM?)4kWLW$%X_mzi4cIXBK55Q(R%a8tKd>9BE$ z1+kxs#VAPl#y7gl`dE)cg>R!&GqF@wK+pc`h?SFPbEyN7y)&ae`99aLZh;e^uu34T zcbu;k4k73D1^;ELIB0j^tFZl?;IaC{{<2PcztQm>yB`?s=<6$ckYw8ndFhi9M%lQI z?$J!B^xe-ERvh_CBkrYwkN!Ls7X%Kj>C6ZC<`=0Q)v+JJ(dfW#0{u8>l=4B{w{6S5 z>_p+vzqeqWk027R8%C^MHf-@otvkeSk^;zmIJMeiXvJGA@Ar-?WW~nqsyyN zJFbMtbqFUE8F@_*L~2u+aigG8kO#y>?Eh_n|19(3Q(e^YDeP<1v7vFV+=v#6jDSFp z;#Lp$|7(G7cgLB^4A*~6CCcI-Q;A0o`DjT9zz=mpHkYLbip{T<7&!Y2I0QVy@v2{byvaE51z{tLhHOLUN)~ z@5P>OHG?e%DyCR9l*i$m%KAgHaxUqD_V<6(zRV&N&5=fdzrMB7`m7@E$?F+Gu)4`R zGNEn$=dQhOW_;Qc(gXxhQ{hRJwa#zl(eJR#L#sFWmv@wcsGU{xGwZ|}hyp&wVylIX zY)xo++#S)ua$76%Ox8vS^!MyvghYJeN~GP=r|I&U=ce=`Tm??&8~nmRcm924mI=y^ zs`)z`swHEVZjRX0b*|}cJ8&%2gBro`8dLg zJ725+?M@$9be|!>;fY>U)w?q#?i@;T47QrJN3Gg^N1IY&t)7sCEOV*a*+;APzD#)oYqQk{fvvJM z%wc#-4tOW*G$}`*ne}Od>zTzTzMf6HF?pJ(-_cP?na{IHAAm^!A%P#+54!#PbIFY^+Xl0R-$PT86s6T{Sz!Mpa%5Il<=qDR7cXBPR1R@Csl+}qw(7VEzgC7RMNML z9?-Zt#D7>7*L& zIBjA2XXh|yj_@{^^u`fd=)E;#=sLtp)|}VS_^$nNa9W33JX&Z-(mR^_nYKO=g`fjr z%7@z=m97OkjISQh;sNd_SZ>{_O?aP-s+qIQyv>;M>8r-1WyOLvW!YVa-J`&3w0-Cb zB;Y`4bNRxn_-WZQv7foDx>mY>{?`=g(`rL({rfi;_|A`OHr{hg$Dr<~R^fcc3ELe? zJ&jcIsnB^FTzzUz^U6`4J(w(e-TvSC7XOADn4-6ZhM^onR!KtEES`c zw5w9H*!xC{l6V%;9S{|%cM6z#me5qshT5}kVa5=w5XqlNd%jc;GwU4V=~Qqv@680;HL3ej@7IjuOw`$GW=VvJalpVc)~>A zq0>#t?vw2l)&zR-9<5*KGZfJNGt_o+naH7C_0=BhgoPD5zNVp`Op;0Ag_NzWVf(m$ z)(J_Liqy5=G-s%bHVga8&#R68V{RZ%9Ze4S!mq{n>&u;=Enxryx2;4us!HDnDmFe9 z4^{pM5EQZp^sb!?Xezt+fow-H_*KIy_??bbN#mWblj7W&8+Sz?M7qK$B0K#h^4FB; zZC^m+FBTfQ8Z1nkI6>j>iPa_wW0ZA=;Qc$ny&-|#$h}L4>8x>?;+m(lXbEtRR^4Cl zwy&7=l{O_zcm=gIb|7`cF>?f}4^`zrVI$k^^R7sJ14xP_{I4JUo_#WI*2s=3&jQA; zV}5V=kRG|MKz9*@s%HtMfov_DDgBt8x*1TSrVluKIM8? zivY~559>v_hBk)_7G3)T`35PmC4q{)M`uWGpJH>vGzI;+BupaxVtNM2@0UBfWO`L* z&e!U+J6KFIx;OZmxo;hmsPkH}x@vr{-l1ciXw27e&ha&D8cJ?3-Vt{NF=bD%fj#R{ z0IQN0u>lDcW;l{yV)9rpP>oa8l=kA_s){gYw)1M6(b@;qZt%%=+;WC1SuHX2nJWkT zdoyx1%Cy+^^UM@>#u_^_l!kdF@HX|hPSSd0f~7(qy@KGV!_|=^mDr~!l?r%T%hT75 zk&fZlz$V5ow5YwadHmUj&GQ1t!S9vGjZd1$tzr)lkh6JUuyIfha~PKD2uUN$+4Ldr{6M?2$%_PGG!IhF zB5I<{tA{yleP$DtrGRr|Oc(9_QPR6GdE$mL1qYC|=#EwOZWpQyiFRYQt1moYtNUZw zrxkGgx07ELj}wfV!GC=XQh~Wx#FWy6pr~RDff4bMw&G~G`Zyajl5@7dm z{z^Q-QTepDk&>&Mr)mspEpft9eQ*{T_o$+Dc;lj7K`XT>zgm3tvr)dpz-I7K7~9F~ z+2PMgm4jepBuiWQDq;RbB~{MO(p1sYKG3m1{(H?%?>if4+k-DOeJOQ-p5PQrl*G&h z$;vNmGW13%pWIA8e&V=o`taZBM~xmmZBHjZ|M_Wo>NP6Q7Y_71v!ihqu=|*R54#*A zela3qPgh?}6KH6!Ey(ZhYr= zQ{kTTyQy&F``=W!Rs3-kZa4p%3U_%N4oCz37dYaN1Fres0FAXpTMz||sC?NqE z=)e8*vT?XPLHVEl`CB)M0{m>$g}v+0iYY~Xp3?6T==&BR_50io7dMlyhYLEoaf!wU@^Mc*3I^ECe?ZCkF+-OZcLHu z<&02WJHj^m4gvO{6T+k66N2};Lw(`?)*&Gjr_?s!Tfw$bRPrjygd)avG3%E;AsVdx z=N|Q>&{b$9|Ak1a?Cl+09S3+%yk1l3b+Gw{Mb?xA2`; zZDId!u+|*-d4a@Hh^=wA3&*3bcIug4+CL(Qlm@kK86Z{sItX1s7DPXuC5hxc_n;P! z<%l}(e!ME-0JeHWpfZb@o$bH$$1YE~Y4wFxfi#-`{y}tqe@cQjpJwhq@xPk*t@gg6 z^GQ3^g<%3`Qqj^*Y|(PmDIKQFN9uZ6YYe^jU8~umU_A;Etdz>G%B=*g+joccmUVvO$7;&llvo zfZ=Uw?o`{Iz!K!kTG@$@Re!3dxWZZjB7dCVMaoo>T}{ce7QX-eD*Wiud-Dj}4v%~d zezYslp~O+;_2-uIf-6G#ps6RO93LJttd^h~M~@KLjJ3axQ+2Q5Y6kBCE>+4_q-)gn zw53H4s$b{ZiEoTc>qdJR_vnvR2LfP?>8OWB<1=rt@mo~f%V-Qpah988rg^QWdP%;k zlk$pnhT1Rz_E$f4^UFYw%R(Dsw44*{xV)T14*wxA?+g3<8>#|JXq|e!5{WiYB=(uF zp(t#VAVj-NOyI4rT;UBY$1UXpV?Dkt!m0mo-UWYiB=_8KPCPNTj-VL_9jRWTpLY24 zyr9yuE@3AKiD&5EdC~I0HX@L>O+tYI_^kWl^Lig>?a$Z7c;(ZPbAx=yrAif8Y}7dA zu;%v|>qHdDr^l4%57c(d?0VaO8uqvDcFwGV2TFh0r8D#p%PzOfiSnJ!?e)JJDLrlK z+#wEIQK?T~wKoat_=yS&rzoS@G_K{lefka!yxbEsJIl(@Io@IKx{ycx4H_99NZ8yl zJwja^4Go)fEe4W{hbTmWA(0_*rvU2R!<+h7xUG&H?VyPYtmzK&L2PXDfyW z@7}F|?1b#TFJ{{8RDQw59{Qci7G^~;jF~hppb5DSgSNhd-Q{LZGaHQ)D>zt1Wj+1% zGSa`j?Np`so!!BDdYI@vhiESV=H3AjPg&TB~Ff|lt@`JJ7Rq2{9fyytA@*wYhjqS_fi}9+O9*hseaa^{|AK&FE z8Eg34Z;?%3?PX6J6D1PMb$H-zDVQjPf1%ilF`Wf?@g)2b*d)WtdJ^|O73%PecyTM3 zY`lCQVc*neuRN190tcg~h8KeS4icn0U3Sd-R+pdl1Q%I!AE6{+-|ve750u(ZeCLk6 z6~AO0u8YC$cpm_$hELv;sYxcEB-@W7J~6E@`@j=gblDJ zby0epMRa>{clyYl=iDt?Out4X{S~lbtfC$FXq2U-n#-gF&(mb!smZ0s^@m^IYUg1t zDvX14`x6G?uV&)p_E+e?a*G#_lUtVf8@WwPzWKICrr>n-3GPgJ*>FNFJOYW=xVk=m zM&|!|Tt&fQ|J$4$IK0cu43Mp%=e^w&U-H>i`Zn2G;tD=1v+|o{(S`}yQgZ_$is5L7 zW6Q6zks^#)wQUsuCGJ#bu{dx>ePX7d=a2q{wfX2x#{=CFIMP zUi+WBo;vEblmxZkF*$p)%kL@IOn!BqZPbiJ|J-cMr*SL0BKfmNz?FSpz2- zg^THjn=7YXS3ye1v^N?}=G`a0?lqd6t|;JT3}Zn7g=(V zmcK*vnmVsVdei}JE^*<=$*a4IPq{Yku*0Ovn3vb1ND4zAQ=iN`u`J&5IPk- z2Qq3;uf8j;-}LxsHMM>bW8H*J9*eza{NIi2X!D&VOi57{;)MrTlc#GXa&`7o4``7h zS)y}aP=cN|)iLQp-w;66(<~Q9-Apbyq4-|g-Gn_+3oc`jQ|HuA1&2r{!+W0Kl4U|e z_EC(LVcm6n(s3)-weU!%qz%b{t526iyF`zz$GqW2`{2W>*DKg&4Hxbrhqsj1v|ppg zxr&Hd(Sgs^{+dwV2VOzdF6}8{)MKXCuOpGp5={~Vl!cR*j1?-w7dDH*%wZo$(1vzA zMOxzp2U4JIQnMz-BJ48eFY6k(I!+o+Cb6F+gO@q@=cE|~><%7WAJ9XTrGKmGSU64K z>p{(2U*4l&-nuhVoO4YKUa=x4QG(hIN0DcstN!3|<@%A?{=qU=EqlKNeKMDbDQAVn z^d@$6T_&E(&$S-%u?PA|ZjfxBT|Yy8q#aE9&Dy)l^a}CTnxILtk{S&5F}A0V3|8D} z9}*`CtFWiDu6;(lnVuTM!|)0!E5OnL@43`4R5{W{n}=HH$ch@0Cur)<+3gFdX6WXO zC8;eur*0fD?|Mb~5I)*`&{N;R@7t0EwBGmA5nil*u@vlkjpdN@;TY?sCU!T^iDdJJ zY?sB)UQbWc6~g5J9VoECcsZ|Onu{?l&2!hXlMyB{3-{6jp1?)5t z3Z#0U8Gksg917kre3MC%U&`3d?ql~546=&BWOHryY|rkNvS{v_bp#Aa0maoxeGZc2 zyhKd9vWa&A_Ep`3BJNH|J+X_~kEIm{lQNM&nb;Y}j$FANv|0s!2Y5OO8JLiC7?du6GiSUDmaW50Th=V@~{ue$!jDsHz-@t7rad7;jnZ})N!Z(Bj zQnNR})J2GWJ)tN#;@N9A_O8RmJPkqs|;d{+?g6 zE*KUVO5)91^#!P$gJ$IG_+-k;pbSG|mY>VKf~AJ4T$fIdW-p@9`RC>17;GU7rE+kw z6BbVNfCiYJZ?pklfgg=mUt=jSIj5eviD#&VLuBqn+;i~3x1>jY?P9uh2zd`~Yvp`!PRFx#G1&Y)*U@SHgM2%w5XS8bm8mY>S--2# zV!*uLLJikrON-O2 zOR3ac;>>VgA!46w&7)oAxm)LN&qlfAqEdMSDuu9`YjJPo_^W(WfUszuW3<>|2qIXM z^0Ifo*f-$-;%i*2pt5T^YjGGpoaNIsiA@M3Ebqg_29RH3dAL-HQV0@zYYXuPAu|yD z$KY<1We}D<|G*0Wf^(6e6f8{+da_S)&`}y)d|s6($8+=?cCPCiwiy)~_Dn=nq`nKa z1Q?-obF`G^@8uMDVsmVGqalOak-#y{?%5p)ORF^G>}Az#_aL&yxE zdFKMtQx&-+y0A^X3??ATBf@WA=21@YwYG*Z!&;79;4Qg?I6Xlh{H@mk-xkzsb$}x@w zLb>fM$8Bik?;1wTL+dC+gNeK12XU?rmgQTJ$T_l7Fl7sg zmXl4Qt}!USAep**#&64aWg`wb;%sf`XC<_fc?yA#NmeNo_rE^l4k2H>&U>MFZ-@9& zbIGFV{2Um%)70z>&m=__JpKtiPv>qrc(RNRsY~RxT@-!T>Gr9#_W>|ru#@Q=1Z}co zvQSHyWdrmamaahukf^Va0#ypIce+|Mrrv%O$+|f|*r?UH|d{4>h;UCw67aTIzgDEI>VDZ9Gs`eD@uf7}_CH(trU!wZE` zg*1p$V8!P z`UlFdp>Q*Ga!>MTTx&6&@k=MXqQeJHl+fAJ+#XhRa__TN8=QIkK-DOZM$JKix$3b< z&y|7bCDF|9ubI`lN|b=g&GV<^g*>*^KCuJ}rajvVe8`nxo_i`-Cl*ma6YM7w=sF<> z1ytz-3;fVxefoU(Hps{0X;YzOp8DGG=wqn30L`-33-GIp3!hp7-S(+PoDLK2-{|mv zCPL(wa5`+Tbfd$qt2ZLg{1+$k5C5rEHo8p_-XkP1`}^OLL&hHNC+z>^(S|ufHX?lV z9)x3w&>z431h*K{?_bfk+{Z2EzkjnB?D!@{ah=?xsK+NaDJt#+m!hC2Hz`Vw1Y*=d z#7g|+KjSC#r#PU<=?(DRg8%Rd^2Lc7rPi4|i1EdVa6>@E z5=6Kmp!*V#Cj~@`1YQzExFH}J1sqTEKSMUZByhaH61aFxm^BTkI+NgxgvOkS1T1g8u+`}jgBQXuY&ykkhH zn2~*NHCfzgxSPuy88477zlA5PwBfqDD{5$Y*AXTS1R~9U8q zjGs_s81c?I^rbTVi|W$oTU~M6cWg2Tfp5O|Jf7b8y!&Selz%W+%`H)Tcl7l={$uth`V# zFmlh?JTv_=G<#7vd&7J{+04Upx3sQQN9!r2v;ng<>+0sBo0@_@0mYeE*N>h%a*eU? z>Kw?ek6QwNy81JklMbVF|VF+wT>sef9@u9gbHtbaI8;&EgYMmD@d|o z?Ua~)cUC&|_pz{k5k^}NX{c-qN z{dNGd@1qMsQ4V&!?JIYrTpiIfHnHw9IaNSHZCZb|GRL!c6g`VY$_Ui=VN_+Z<}o)+(|OTp^ClgqJ=pa_>{bL z#5EDN0Pe?@dqgQ5-D~7*@*9Xci*~)0V;fGPcC?+8PFB^MMm^s9JFKYt@gM3Q{#NO; zSqXCZBTezh=O4+KQsjFGCY~xDk7`1vj&7e#<_m_JtScjT%|qs7mKlNT3V@s@@r0>b zCuI70Xy`+hi|XcHREgQsm*>aj`P4sW&#*n-rr=M&>P*|RU)&Jo{pe1>dRIziL(hsA z2Kll%3<`oJ`M$_hYuoLY8M$tj5QfkBbIc46?`&bMO3cAaPxm3gg{!e6vsoow0E0qS z(gWydd}^kpdGI>T;%5xQ^67WdeYdhCJ`Z#+V?u;|f!W>NwqSy`I{DlC&7;^$^_<%n zup&$dDm}(%5a1V+uF+0edMpHAwf$p{cyg-n(}VnI__2`hp+4VYhqJ(LX9nzIdhY3( z?SdDwPO02p?E($g&jR$OlkoX&-`eA+d;psJOR46WOO}3IK;@&tOe|87(+iyU^X(AF zr%GSDoW{)Gxh|WD#}uk8kYTXv>@XAXUcQ94K&%nh2mdoX zT?lVC>C7eQTxRjwN;mn*HQII`O%1dS7)NtUSiC2Vu3SmdlM`ez%VC!2dFU}Z8V32X1yd2?*bTX@*J19&g>jBB| zL4Vh)ZZ>!ZpiPbC0C4wOz81{BTvtc7pFe)tC$m3W7kgx6Co{NsHwmp}%yZyzH>7aR!_3BI&VH>>O9w9)-#E9c0+ zTew0+y$FxOOxMm2c4j2>!uD39>Lhbk+2r0{`^a7vrk)mH*ufW!?uu&$hSG2`2Nsog zKyrhpVZG{i$0KS4F4PY16m8o5xF(Trg?6&&6m9~@zn?{H?5uO0GV4dI8WQ2|#wNGN znK+vNn7Btza3;?73C_d~o8k;Hs}&?;hDZn;p=UzGJ`k0CcP%a{5CMc2M(iu0t>J|M z`85~;+-^|ZZB%BM`5m8j}ebQCKc*s3vHU{7?huZ zS4`gbs10_V^C6o+UGn@`GTsT(^Nn-#`V+~EA-;M1{=0}Sg zmsAQ@zbtNjQTGjK=^jnpdHlV!MAES(DG~6j%IupW?AIJ~rE#R5K(*cGMpVIw$h|*2 z?Q>OOTZ)^j-r>U8?Lac&$k!d4tM12&VDD<}-omW0(vqz}P_{v8n98ai%NoP^R+wT; zk!?XA$_Q^Jm4e1d>XkAk%lsa9S8m^(-d^=KH8qXZHJY$A8i2HV{u~oG#`fj%JH2i3 z#Fv1Fi$m0OoGfd61Zc-t(JQ&GQECDwaWdah{;qG`59FN)!&>;Y+x-G8H25LL;5y{+ zyr){>Xx*5ndx*;vQ|9Q%CsC$H%3cp9R<!$qmj9bPr&{mowa%E@3Tb@(0Z zz2RGsU|}IIt^VqA12BiJj62liF0{>DkH}}Y6wbWR`?Po$wRtx22tiIP{@J>`Ovi&ElEl`s=sB&Gsa^xOy{ZUKKy{%_p&2AKkN8f(Mc zR>S%1`dPm6I^VTe&N~F^>cF}ieH+xZghKx?`( zPul-u>#n1s>i+oAOATEjT@NClf~1s`k}6Un-3@}$9V6W>j6nz}AUTMX#LyuzAe}>x zNHf4N#LQjKbLMyb-ru_au@-B+&gblN*52>4_dauOo25TSK4CZ8Gc(b3ahSO-Sm|9M zgQydKRiDMV$n?X>?Dnqo_~q!(xeTSRx6s=VC!5DrS#?B)Qk69}!ru;)9oIw>ldbA! zZ(HTHPw>URQ}&ArldA@cc!Yxp` z>4QasulZkWY4s0JgB#bMf1PugsA0ow-+#a^c{gbmM^K|Bzhhzs#5ec~D<4s*H3@`W zoJbH1WVJ(!S6SWBX)4gMw^TwyuDPSuVm!GScC0icymZg))jc1HCf!i$q}1yWq=`=B z^`Pr2Ca}@dRhLrfrc?XOlG@Estt;?(yBc|Q84kvL*hhtgA&`M#d$r}t1-eNCDU)Rr zcTZs8D;&Hvoas!>U4Y|w&glT0*^L3aE>cnzc3q&X11}Zw-OYOr*+0U0tfZ}1`KQWD z-gPLPh=?ss7I9TQo1t=oVZ;`&+sK2Jk&v0{Dndoy?~GSJxAh+6-;cXG<^SGgBGRbz zVUfE~7@1qT>qn2eKCf>R7?ST!dGs`Ib|M}n*qa=&ol$Ll`Qbd$16AoZgRusa$amMX zq@>VBY+zpyIY#bTZ5PN4`I|3N;lgU^vQddsCaygvKYfR@xJ7Z}TMPL*zhZ5{wrR*yCG3SqwY=Sc@~44#D+-D^ez!K8%r(u}e?b`r&qVj*8{@ zs^!^$Rj_qn+w0$*kKnE$BQD?_jhsZ@ql}c>*0NS(994`L(+J@x`048?-pY*Jo)+uFWVbFi_=xqmiWk0hcMq%3;Qg_|0SxZXV{b*EvAKushq2L_3p)30Tj@pl{r zssCtl?ZMhg)OViuvjl|ybT4{aa#FK zE_)D@s}=y`a+i4%WQMza%zoy<7SifK*s^%#J5#!)V!4*+3Y|=T88Db~GoV6?D5N|C zjWjYK2(bKa^`J#ijJeGnTtl5Fn}TeTw&%_h*mwW+&0_~#6GUlVT=r(SP=mc2T_-5Q zTE#hb?ZT-o>Yl=c@9O2*-6e3_;by5$?jRhOsJPfa$kuytHH2lGm``x;3fyH#tDbM5 z+k0P2VQINcZM3AlP&+ZYiahRf)61n*$hjsPtCQ0`O&;HDxaSt^75-TNjDuL^&rz$-<6%{rlrM@_jhJbsjzlq)Qt~v5q)h#?|hYq zGV>cwI$u;8r_Q*8X;WpbRbkklGBYC@)PoqUxrVX)5f|x-%e;N751s;lHfQc;ARp8w&u7zN?to46uvzJ)C~LemS!!wFt(p*RTvqcj@~HAnZHda6P#4bXZJbAC3e{_uyAiE=I**lz*$YQHD>++e!B1Ng&pm0| zM2@gmS7uFy3)NE<+Xt7bVTcT*fYz1@PD)ej;L-*02XuA$qKxQJ(KM?%#!CHd2c^dQ zPcVOV*X7r(Y}pso0qbwDuOFnwZX6=+ZQu~c)b_$Rao?(GD=LT8U|yD|eBSczODVbm z$rrXV0j>8gm#=zF4_mq~!Pi8w>@8Sp{2b}>6(JcUNt%dKlA}j8mSFrJ+VYM)#pCbl zDZv9{k+1h39>#u~-(q$A-XamH&O($Tk&e;uk z$aV(i>df$O&A8~kCE@5bIaM^Cu{dR9^02A-huGXc+yTL7^N$cQ`FH5oJAwid)D8&~ zhuYDP4*P!|T?>Cief`Bl>Iob}z>8Ym@W2-mxBGtX{dma5Gumby640iI3J&AW+j~y` zbg<{Q@js7(s)_gQpNP@jQ)A`r$YWM(l+t_y&Z2SGZIiPElD_pp%pJ`GDg~1GB-X-?-Sz_{w5%eK%Xe+sV;NN`w2b#*AN|HNI|L+Wc^l zSMI#fcryF^iO<)BcP*x-3(s}RsqP&oVcwq`B0f=#A&&JnuTAR6-sYcD!!YOGkQ#1+ z%{^jw(4Ldr_?&*1`6_MuX4T9S!_-JWglF2U!ei|8?&sIL0%1>-T3dc;KdXq`MEIq* zxq#!`zNE$_vwbPq*U{aLiq(FFbXJdvRpeqTVKsn17L$2epwm~n%%bttJ77k(U85(6 z{u{*?GFW;0`t5T9eOc6Amos3&z7(q)j}_M=8QA!wc3u>UPBZ`52s^8P z5q*^TQpoe=Cqozd=f%;_O4QJ{VDl>rBFidJx#Y``#jQkXfg3X|sxkG1%D3@8 zTqbmX=BOm#%cfy_bt_srxWjhC&M)U$ic&zoAe%tzyw;%f?307=+~Y9evMij+wEvYR zcvz?RYvH8IY@h5)A!KR)@L028@$D5pk+%wm%7M(Z^*tdsLIhMB)FXUN#Miq8>Et&f z1KC5zJlbiQr^@IM6)`;X+{s#|&z9^&Cz!8YId$9~qE%CLZ9iNUt@t_-xg*g*NgeH8 zOHdO)K&_H~`zTdi-Bl=ROa1;NYfbfB9Qf6d3=7k6&r%3O6*x0)PGtDthQL}mxkQj{ zhR5r6Vw({8)jfERNjy34l&YKTtKNe!O2b!5vLrKLX`I& z%R-XGdXsRM3^h%IQ5fX2v!$GC)vn}ZCYf;`Ni#%OAXHt!ObesXne29Lcc;VbC>J$r z#l!(ICRRwLb?x&sY#_xR^XGryX@nn#6E5ilALN-q8+ceBeH{9Y_&|*Daat)Q=foby z<#5J+&_T8vUypq1bfdA5th3eI-TPjgo4yvu)U364Sj5NMSGXk&8EZ+ z2#QK~$oR0(D`D5 zy(ibKR`_h+R%573{n;BL8N0KLRy#w_ufi?EzVtQ*u?|rkieizS- z@Rr=!$54%xO=dZ3Lx_YM*GU3o@(#(cMU|%Im^aS#O znq5@;{Ovo_3&6q4I`v;VOb6AV!xr~KI>kBK!gx5R?k$i78(p-Y2a*uwIr-%`=BIk0tdq*ZJ<;hnA3sBMvHd3h{X4H_uB4^FjfD5MvuiI1=_9Bm2$chf?W z!okgku_$Am*AacvP1aY|U3~{d?<-2i4}*T9k|`_`G4;_69g8vC)`7TP{l(hu3-@uY zFm9_<&ID{u>i1Q7uePH6FQ4+h9bM-*dwZo|CRt-%Vf8+P+U#s0GTA0YDPdc#Z1O(W84DcC7sbW?qOyiqH91Etz$y3&$r5NRFQ>RK-`(tJycXmC5UmsYLq*DlRLT$G!6 z{%RV^qhX79D!=k~IPRwn&g)7V*3gZK4f#WC*4^BG$cb9%;bmB9HznG+TDlpaHP2cU zaJ3#bWcy(Z)G!_G%2#BND#&hO6V zq+|{p5jBX3)7ct&1A8^yvBxz8vFStS_ZKc2=i}tLviCI-9qa~sP->;M%W_+q)`2+N zSknIe&pE}6s4beLn0@2j&a1mf%Kae~aI1Q15%f;(ey!a!D)dx<0nxW{IWQ)eWDB0s zriKnCCPIs_PBI2A(P4&QP73Cj*D+@2GCI|1aC)5-Gmultd&>FV*^Yrq^eEg#OX(6i zMZNvev~~F%nWcN{)5L&aI$XXs+WAq)V{>{Tcmr%sn|B0VCr}SMbrPIQ9>SG0F*j|133U?9L9841gb9^gFq`NA+NEL@?Cto2p*;xY+)fi0t9LzpvT+f8Vg4 zpg?t`Nx5u*Oy6r(LN%mG*DbF#)BIndks=5PjcNXWLt}{-5E@}#Kxh;S1XhdP0`ZH_ z*@5`Q=g~l5z4$5+zh3+%5znRl<*b7ME+7ctHr@ak^iwo202BZj^euk97-KdR$Z_r9 z&Q@9w)fayMnS1;LAxnn04O9GT<;qH=%s$wgJ@bJEaSYCV*vctZtxtMSqtDi~c@YYu zXIJZ5bFR&(2+AnzORrC+xv)0_w{K5FK3!bYCVUTgts0y^FLJtmm799BYpBpt|13$n z+IDQA;+jC~GPveRF!e>Oh^@Weos>?W389qUxo$p|v_El$MEq?MU$O>gg&{-Fn7&Db zc08-NNPkt*^UNPpaO-sB!9bsJ)-A!|6h_dwgsa`Pd43N&+7RNMO3g2~I`4&q4>x}d zi8Z;|HYmM<(2_bfi+IO0VDw8~IIYZr_c1$fiPWs+pKVPrzeQ2T)3Wi>%}@~a!q37% z5aT_H=i_^yyVh~$D%+C+&Kkd;BqZNY6WXAf4f2@SxBHyN%xI4dq)-16!!PIJQl>(l zJ6BXvW+vc*EYzQvw0NYLUty7!QsMvdtDeEL;LsDFFGV?05EkdKOIC^oiHvQFl$Sz* zKj*tMd;9gLz+Ak1{6-n`JPMQ4O!|%nFG%4 zF=o!*qHda7*Rx2-=oD|z-%YQ3@yV}flScF9gF_Bpdkg2BS8D85+9gGTt#Ob*`n~sR zb|0hPew2^s+ie~#YGULx^83_V!d$&bm&QN&;Vt~tonr9VhZss?AKzKQiCu}6U}N)QQ$Y}BvHl+r;em1ZfDdS8dNw`oFemyA}!KSZ9P z5^jBOefuW*Jkr@~xUWn^yWm!oMt+QUV@)ODRSjW&3U5VfTjCeZdCz>5W|H@xcFI~@ zC-}OVF1nOCtIn?USJ2&)JDbnf(geP!!})O8F88$r!MAMQ@y+gv@`{m>6~>I-uVY~3 zsgtRZ;hxSnPu6~dK1)BeJ3B;Bv6FslX|l^;6LwnXHJW)nqBK&9^i#W?d`?|^>&`dn zj7t&T_tAai^}=gxns=MJxlXo?^W-64CD{y5RT$?lUkQ2#pu;6YoCqAgI_mC^4Tdn} zeH%~Bhk|F9a(7gel@jY4BCM}eXPR}WqMcwdl@9Z7<_q3DOQzUNDqVp^xrs(OL_j4u znaXRecbx)t`30lOlv27ru#>buF<4$|qIBC;Uhx~FNaHf2m=4Yk$E;Ud>v9m*M%bra zZz312e;u{WaMMN;%pz~hLPq;)`k}@7^?BrY5NbA@rfVJ?S>&z*gqogu0yY3C5566{J0-qhDzQRezF2V zb$H--9k1Q*zDHc`Mqk0kY9Fp=WHK3UHCr%9$bWV`iR=BPbrTT{q*to|B0fUFM94#P z5)Me3F9{j=CO*63zmqHEA9amd?fD}M;RLG66^GWSH4;?68xNG9KAuO zx4!C3HDA{L^dm$$+Mcxl^eEymChg8G8TF@WyaffeX)gbLE2mu`43&eDhsz=t(YB6` zj@cDu_wh z^>aY7sn3+$mxCrdMvuBbWb)^8iUIb^dW}VmL~ZY+US=EXH20IY=}8bS<(tJ}yl~N1 z=GCzC_fLjIQqfDERG63C3K7%O+m19+U}r+OfSEttiTs}rE6*y+%!iNxo(y1f4`-2< ze{7Um`ce*!5+musZr`HzeX|O~h6^bI2EWK15LcHU5L!^Qd<`OAFu1rey+0mjdFB&9 z&r!ePEpvboU*Co|Q8kBLl5!XvNxE@AV5~aHql}#|={UkP%<1SQA`67Lq%@C%2Kl=; zFpo$l`mNs9G5OUWMJiE-ab|;2m{Vbc#1k0%z_vp17=dSC*kekxcgAqYgzKnmr@=?& zuCE#@%ULH+1Aaa+%0c`HmUZe5Ybc|FE?D`WJJ!jxiNQdAhD_~8mj;qfdRDL_qek(A ze{xQ}6f4-uVmB_glZYgGu;$kzM&Z(fUMq3G=Ak;Nyj9%eC4(!;`dwffl;jI(*vb-)9nFn87e_f&B-%EI+G3U!;dG!3Q5V}OWUM&9V z_w}w7`l7mnj*Cni+58@L>AH9B`eih2VK}Ftk8pej!&QzE$ zpi*lS2osqMjo)^CDudvT;C`2th}65Xrg3wCF(C;7cVZ~}E;@IIrw;7=+pHw7ez{+tRzkEfDuQ>LsIxCBMSE>=L|P=! z&cSQ*lkU+QA<@$jy8CX^JOS#@ZwtY#7W`Q-q*XpT%+ms?sjPVkA!~9e?XgBs?m%pK z({8CiU%o|?DgRWyaVP_(j|z!-YbgI{ftQyv8zl#3FJeONA8w$WS3h{i%@_A|zVdS# z!)at;4mOUg!AablevBhz(D!^(sp!);>_0c#$9C;jwsQIU1*+l8bct8&?>fPOD)v zvXX_e&JbB}&Jx4bj#)=o%=%%AfknBf0nI@l-U;w^s|oFr|p^@xvEmN`Czzt z_tw}ms0)uryv{9-NjA#F6C8oEI1AD{5z-t)qE9HB38ck?yuWF2DiKJFdx`(0MIy5d zl7_<77*Xh|jzL2rBj z60J-g31qZ|{x&%D*`xtWA1vYe>xdiAzEr%GC2B%q#E{qO7P44M*&`l5B?lD{CsNci z70=R~d6D0>A`+i=zJ7NBb?Nioesz~d6-4Ci>`i607eX#%|Im~wD+ntO^A1B|!eDTu z>oFBku@i-vl&GAo1^`qCl%Y?sVeJiYjhkle= zw9twvG8sA=iE=&V9yFtRX#pBX-=*qf_u1v=Xw@Jy?Sbk)arYDZDa@)0XBY{h%9-W} zaA(^7a97!%+|KT{-HDW+;s?7mJ-ROMM>f7P+m+zqC~X@*pHb^sGCKny+4B6_L%+|W zM(_h_)=E-iCE0s9I(((~f2DIxvAc^e=~!1pDL-Ledm$MJkDB#>DbHES_cGWGLzOim zjw@9<7*)v>U+H?Lh#pm*W!0fR6H(VcTJ`HC0RPIW+;O9TwkF&29)B7epwX;m7?E%i z50eF#=iIAxD@~-*NEusvl|+y_G=HOaoNEf{Pa(n0c7=MRTz`=Hv12LEnq4H8;d*R$ z`9xEOCd;72+~hwBnQY82scik?vR$aqAmzX>U91c?JbT~RXM?GP210joh(un{<$)u8 zALiOG^~XVm_^}QP+PoE6O+T4I*xyc9@gF_GQfa;)7p%6ue|ruG#qVesgVwgFaB$UX zotM!jXA=&`$#$K7Zx8FAeG`Q}$<<5D`9qH>$AlyzEU1HiB}(lr-A_aR0Sj?W z647xLG_)s^tP@hC7XeSDhJ+BCw?sFJ&kq-O#wDhQM;ovPal=>ErkMoXh@NZ~5M96z;sF06^T9P(8 z;%9`O3X6}kD{n+}cYbM?BKO&jOMYM*8WZS$n)w;boeE#Oz!^NPysA$;M1YY!jq*W4 z7D;MtVg6cChXXE3LnY_?y0Ech!W`zS3ijaJ)xI2`L)y07qBbTWI%Akw!7pzcme6;e z!RV-e1@1e?Y@*x|D+E=k00)v73vLu($^4bSHrA#-yPO(HBWa81b=B4-E~zY4{!4< zybhfa5CNBj_@yAgKV=XQuVb>sShkSYwQVQyI`{Ky0^?U0 zkuIb4x|kGTGNU@ECQ9D>R_@l6xv9DCQS!Eyu1EC0w_VM?=8YdFw^?bwlHN6QK6#k8 zzR~)oCj`S9hA4S$VfQKQbkX8Fe7aNNx5&BcO8yHa(Ist^f1S$&BAMiC8*Y|;*-0hz zO-~DvN=x-d`RBlm1;r2OSCnX@qJaFnRal9ij~S}O4~C#B zU@(-Z!ViX+Iy{&Dm&>jKxT-2(gk`TIX{gEgcZ99Od(m}x4^{_wJ9T*PTPuEWefQVX zsRul#dZ4_C7NEQvt$0qc72t>h{{5o>BtzJW=Y~h{T<%|vtPSA)X#=?A?*BN#js6Du z?<9uAgtrF%K8KO}j{vPG1?(37_i?OYsFCCz31RyPKG*TN7+Iq)m}%5fgsc{(ClrQwI%P^CS;Q2)Pb{ zgtUGJn7aRykiriE^Zg-EJm?H)Z}l^LdwZPWFJIXiaQUXs@a>&<4bs5`Vgu>6E)*~k zLc~momJAZO{`2xq^s(kb)rLfs_IeJ~Rn4;W{Z` za*^RpO)|i|P6wFK%D-k68DRF30j2~k-t?ix*SUlxVIj<;1Hb7Rsz!$jt0wSgg zQY2(H05ClRe1TyGfTm^vXrs`-+KK_7VGIDx(Hvi3i8%;DZ^A49x&92qOgLr^n3NWH zQ^o=?vG#yT_wBFw(E>1QEdcW$dwhk~_COOR*aKR(JzhJs2ebw^d=q~CtG#dlG&cu8 zn{~x&tZsm&;s$7;Zg{Qi-!)>8455b)UhDg-QNIE-zE^;j;f>dRc>~&|H=s%R;59oR zK;sX=pJ~Hit=9+8mV5wBGZ?SM1p{~9w_rfq3C3%zA%M0J324y&(LzE1?QIC45k%rO z#YjMNjs&#ANW2D*1hkAqd~HR4YZH$Gw5L&k){ubLjuQZlD-qC)6G0Fj4k{UfL;%yw z1hCQnx#@l<0@$@A0DF~z$0{>`W}D6cF#1eDqDwiN=TZtdT*HT?*XULOGxQ2>xc{}h5CVpEg?ki>Kl zGvU)hz>F%yn>B@i>0btz2mfQ)0cb`)0Ijgz1+)*NfHpCT*9gV{t$PN4o;80p`!PTZ83VMfX}rci18BN4fR-?W*BWL3Ep!>s zMqz(7wpl4+;hNHCP@ zrSS!IpCgh%w|jcnBd9y$HXN?otET%9>+w)i+!bqOTNSf(=D-ofn6Gu#d(jEy||mz^{qMKOY)at1P*&)gz=84?#D{6w Thd%cp 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

$rOQsm|HQ-xicOm3VG(?st2j+$xrvp4A^w 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�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

mSxDS3Cx;6}rCxqfZ;>fOSL%^q*K;xozO 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�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 diff --git a/interface/resources/avatar/animations/jog_bwd.fbx b/interface/resources/avatar/animations/jog_bwd.fbx new file mode 100644 index 0000000000000000000000000000000000000000..479392d44cafcc172b687730c1f3fec218286704 GIT binary patch literal 976816 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 P@4ne-%`MLq?f8EHV_s^V literal 0 HcmV?d00001 diff --git a/interface/resources/avatar/animations/jump_in_air.fbx b/interface/resources/avatar/animations/jump_in_air.fbx index 72d8fc269cad69e053c82653fb499eb5a50c7585..2e6ad32f4faa73beef71423fc4e8fbfb5f638436 100644 GIT binary patch literal 863840 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 Ycf?sd@|)j2pLJm0>ANQ1Uc2=F0|mSTt^fc4 literal 708768 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𝔄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 diff --git a/interface/resources/avatar/animations/jump_running_launch_land.fbx b/interface/resources/avatar/animations/jump_running_launch_land.fbx new file mode 100644 index 0000000000000000000000000000000000000000..ad922d948ed45a226efb50dd99724890d2a6befb GIT binary patch literal 1241936 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 Q-+6P^n|bkFJFoly00923nE(I) literal 0 HcmV?d00001 diff --git a/interface/resources/avatar/animations/jump_standing_apex.fbx b/interface/resources/avatar/animations/jump_standing_apex.fbx index 6385766b4a3aa06df8198090d423ff24cc4d65ce..53b79758aaeefd709962afc3ced424337ba2adb0 100644 GIT binary patch literal 626272 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Ⓢc=!cwf zKE}A$i*OmQe~ZDtrOD`cr{iIaqt>UgiB~cH77e3tHxKdXQ;d6u_D4P2s|b%b%gLM# zaeq0+-76p-8%I@j?-7Vw=F-e5XFh{?@HS0G;qLAOV5=Wu+-pO)j5jiPuxrBV9SVoB zUZP>b71GfV;^F%kci)3}@CwGgKOi2O$yk=WIUhR^S>(S;)fMhu0P)}rjC(gg++Rd^ z{IhiCd5A}gG46f|@o*`|y~73-T9xry2G9IXlhLa;O*;9;C|*XxgcYQt;~^fIo3p~* z#~>bjfUA3-LpLOk4!&RJ2_z5Wo7exT~*KgoD+hj_di z14dtcQj09cNyixloog?M0L+U3U?obcw|~txc3F&a`lF$ zdiiGw@$NAc_3Uq>CbHXP6DL93{u$%$K!^uxFz(HQxMePBXQiCXVu%No&D9`r_ZNuU zyJFlsY8Y}R-avCtsTTs>ARd}^qHyfXzQ%XnjhXTM5__ZvLSS2RrgxpcJl zaMZK^Eymq5G5#aQy|ECFHW6O7UQXsAh{tA^PKCRlK-}7uzHO**ugVD2YS5YRlyasy z#N+W8cY8xT=!tP}HsLZ}+c=XlF9h`O-lcFDdnpZLZIF)s3USB$eO}>i{gKF`uoLB_ zaLldaF4Z;?5a;3V%UYxcdymgHtf>ZGd>}5T0EnovAqrwd%CTxZ4im_GuXR z#u2XK?MQgKO2RAWhv6_`XQPW{6DuGdnO_bnGY~- zt_Fp>yNpGx+GA)k3inzNF5?X^Bs_0EW6|;UgTut8=bXAZ&xE)?o`zAl`zFMli!knO zg}614@XT82=n)A_qGu(`Nf`G&CS1mA-$S@lG2x}vt^w*fxSDi1^Kl4$P}B_K&b1hKFM)Vuu2EIp zyBXrPvB>{JI{F&KgODbpaQAzNN7rE7v#&zV_%jI)x5&wKf_P}I28Fv*TZ4#siZ6WQ#P^h)u?C7EOv#vZ6WSYz}3BB5O?k-JXJ~ly1NJB z*6kQ~a}ba3z_|A(#3OT~iq&L}y9PNEJVn(N?p_FS`(2ECw-PSnwajmdY~_U2`vx2) zewKzQt0f)%5#rJF7Y`#JG13#N(v~Zz3lXK-^z|arbeEN5)ZA-CG55YY9~k z_K}mRF%h+Dy^3+S6~yf~Fz$^YT*aFs+;5x^?|pEXC`-EZzOspB5D%ZgxLe^`)N}MS z#=SC#`|lAR?I$O5F~q|~7ZJa`V{-b)aVOaS?saxz~-+<$?pE8IP35^}~eMk?Iv zOt_3UG#5{FQbN2}!(nU_K-@q!F(2ZNS?mgTV~B^(P|phY_MD7*j$b0&Z!ITtGQ_P% zG42k6xc>;oy*nZ9JVdxvLr!K1#QlXBceg`4cnjlR(*}827$~c<>Y9IpyfV*Q2Y!S&wnIBgEtPG45Rs@n|FAnMTr? zc@Vb~aQ9P)J7zMfy0_O2C|+y1nfs9m@j9fF@meO{d@I?+5QzI9(l82l?}B*r0mi*| zARc^d@P=|Szd_vk660=zDd=kOS7F@qAZ~v`xYbln<~oRnD=_Xp3-Rc4jCf#RjYz!Sv4%ns?v7kuwlIikLbLcWm$jy)GjM)G<)g}pweIeD1O?C ze!7=sS-YLuZ(#4UdkpIR_p9)~(2L8;8XY&H$AC+wR<(AqENgGevZ{6*(yPb7F8v1e z?r5gcG5!0s&;0d&GCOfK&h6c&_psiBd-cZbKm2d|i;wUA@vEQqdh&{`6A#^5ca)G# fs4f2Q|JVPvc~knY`svdvzy7lN+L1RNUG4t?D-*jO literal 254832 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⪻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 diff --git a/interface/resources/avatar/animations/jump_standing_land.fbx b/interface/resources/avatar/animations/jump_standing_land.fbx index fd97dae92af85ec6725c28d434d625b28edd6431..aaeeb186fc6e9643ec21088c2db14f0b3ea4f501 100644 GIT binary patch literal 1025792 zcmcGX2V4|K`^Sf7*PyZ2!`=n#1$Wi8Hx#=@K{%8M93G&eM$QsnHPK*=UF^md>?P`* zi5k1uyJGKpcCqn(=5|ik+&shX-rj!x|5vi`%*^xqJ>T8g*}c8CAqin2#t>bLrag2` zBcel$2|67ripCX3s8u%fWy{y1X^&R=kTAWm`LH;BbZmqnx(`Cg4I$)(5c2-=>u!1@ z{$=Y&9taJS{6&ryO?%jXhZ~NUa$6s=(vHcac+6tzGmPdge0^s zj1a0I+3DHJ5N~Xq3n9cw_GW1x5gi|=Z|#Q=>Mq?Mqz^Sjhqd-V2*pYE=WHJl85t2P z{_<~0Ubbx)`O69jp{%w<4aT6-2qEl9kkGaU{x>i(en3QYtZs;?uFl`ruWog}hS?Bu z$3sR4We*C~N9$WhhZ}+lAcR^*8v2Js;{QZ$Uw?y>?i#B%3L$YJh1|vDb0dU2vFzXc z)|dPioBKuJFg#$K9oe$A*T;q6w)#SU9WVKXSC@#mNPQ5Fog&$tH7LISkNVI!+b>o~ zevzd~eB3~T(YD_r*`KYgK4GZA7#3^$%_Zq?I_rl-;Oeve=B4B}S(_Q6qV&;XC*N$< zB}JYq&}fL!8{;DMv2}e%dx)jo3)fCyP)>x9UXNQXdLrbB5GpHng){GHj2I9R9TI8#k7kCb7(;w?n3xF8CfZXJp{W>A zR1z_=NlZ*+M5ryjZu;mjgYg?pY+Bg<2Y1sXKF$!Pj~%p~wAV;%5A$Xpfwa92AyImu zH9Y?IAqgQ~UgF3&v87@_OXS$VXbhtiOd4x1HiiNEGAtn^PLGc}{aUu~V#~$8Ly}@4 zgphx&8ou>v`1|_R)A`kJP^*3e-?PV;PRt@Z zLa1FxY+O*t5PcZnZ^ta6ip{>N_$5SYh-`!Bk_H3B28&3?AZ?J5w%y_Tq$yr(syNh? zJd1^_Vx}F$)(U>pn%z>B9{)kw?k=|NBlTE9Nt4jHh#~qwqrrB#lO906!h*-;c=U)0 zNeJ=DCMNKs*hxvClMW%c6I@w95A>?SJD_`GiGHk*6o6iuVl+3o+N|xad8pR17gc$|2iA^a>~PVik6a? zZ%z@h*+ok#iI!x+r-7Iz!y;mBXM~98IGY8nqvP}g^x}D}H9q^VCt=mZupD2*A_hdW zL+_JNY@%DB4e=I6Lv$RwQ#?l~pFUy=UNC@Ex z=Y>N8jfOZws3DRThD-Ys2_wacEeeVbiRl>K!WaT~h}CGETTHp;*OYCS7%?HyL2)6* zIGcEFZM*PU$@T+|Yqx6DKfUn}qeuh(U!C~cfFTBq555$V9do~r#7nBHS$u4qA<8!N z&LMGPNwKTT{4Te6;x8|b0ym6D(LTgDNN=x(|IX|hR~J+BO?RnPv0hD3&@t;K9h|do#*TE)vK8yK03~JG#vSzcuj%lg4yhU+%B!)jFBtd z5E3f{*Rbs>rjw-QZw|#D@_Zu!E}bAlyfIYYQM|aoU)t(|!!b1ikS`V&{Kq<|1hz zQ&X}XUepQC&fNmVtBm+K z@m$p3U?5lTxJTQmp{3)W2N@y_wm8b44{`kSc81VF(4X)BUOa=7b1haX^HcZSIe2@( zIsTANdM76UT!Kv__0eI_$rfkXD8Hx&nH%B5Z)ZcCjnyWhq481ik+z>%O^hT>kh342 z`rGD3a^ub44gntkzYM!+LQF_(tSyzU?F`Wa@c)Y^13dUI{K(u|6%>mXA3CH5JUq$4 z$LA(-amI-L@p1a{1;js;)Gl5WXh`DmvB>cVh38@|`VZ?69~oI4U%-*=o3hK+DlCeFiBnpQQo>GOekhq2-O+>=~ zD0_{>v6VH1=}+QWA=$oB*1eFJkE9Aa#fQY{jnQ}=Iyz2oj4{|wBv_>XB#7JVT}X7M zt$1Lt9fAo69mB(8^>MayeK$Rx>(>-)M;Y-yY?a8EP;Vj)w-Fo0wPtTPFk*;7b-OtW zivyOli?NG{9^l+~`;&IDDsF+|97=50so^dxEc#PjY!)B>yBI^FW5wf(IOBqjlW)n8 zB;H73+ebvJ^(L^0gXz+SLx!nscv2BDTgk14AO^*Rgz8%u zjO`+#BH}tmMr3Qz!!)!y=$+b7T z4O!>aMU*x|hAGSC7P}2uxl}0YsE1@6vT}(gZPXX56sdHD~G;q z1uvtK8*g8hrCLXa>4&jz$Gj)4lo5T$>!K};di`+l+PX?bF;_`IyN*Ir!!X)7@j}V} zDt>cH!OL~+LL+t3lND_r4*g~=mUi>;DrsACOB1*KIwd|MsG|l3TL-csP&6oVOWW5eQyJ#W1ag{o* zgksRhy_zo#ZNdf5yUO4cqcP< zMm6z{GQJy<`mMV8uEI%qFOiv4s=_`y z)c}R`-X^n8p@yQT819Cdam~FN@C}HI?Og5$-cMPG+A+753S_7MN%7aG8DbwUp(#7w%IRFSF0h z3j3^G8_sj6%swmDR+i@LD}F6oq~IH30MUZY8tNvJI5wxg74(ci9qo z^V``9`z+EB%+tC~W}mqlD$8>+qtC4}`!p%+)2$JhXUb-oeZErIXFS}eC3S7MtmDwY zM#{8(0QZSb%k1-t!ajcp0JTMTWcC>tpe)amaG$1IGW*=8u+Qd=!8~K8w3atFsn=Lp zo;%<^t-s0abFIQYt8rkSzSCs(spFL8xft%#a(a$DZD%O#vj7j~X*wgb&uqN1JSW0^ z25(H0H#Zrnu+L9$pSm3~`?M<+(~>pOpkK zPyUn4K8p*=@>~G-i5|=BGf82ed7FcInr_SN)3dp!7Y?&dxOzu4w-$PQP^kKmT;bKGW%@RQdypd;66%AeHL!5EYCTNKHtgg^H+s^=57P#$v>Cb zC;o^CzN0Po9^Gh0pV?)y5~r}w*KnVv8#42}udvUEwxG7?v&=sGv{k0daZLciPb#R{+xqT)p?9-BLzbCChh%rtd6%mWvY=7|O$(Ws_ zFZ@W**VpnOgdXB2=gIcX6E3+riBGsF`j8JkO*SQgl8-fH@^KFw^?N7rAur0uHspQ6 zg8Dop847u_RK+u)c4@wDoki2|D^s!t4Gh6=p=;K&4B3kxh|1b5J`#V7)b&{?IId4j}1 zWnP8`xxmY5WGFHoD#i+2Ab+l*^&f(0)|c!e?v-nOrS78j__;b_eM)yiF@BV`RYc4e zdZn(9B>gzJeyba?9KQ=p`tHT!T~xa6*;S3}J-fQV^+jYT&e`~p46UR1j4ZZF_A}QQ z^d?n=w2Tb%PbV&L!pDq^Qf15ZB|3T7tTXdE>GpANc;}8Eg7O*QD9@M$fd$ zkvT2GgNzLGg1rSS0)9F;`-&Wv8KhasTb05iBBS~nhS}ckDu}Q18Hk^V$Ijc1^i8UC zZPgQ@o?iI>&UF)ABriq5&*4TILI<^u4v&n-FU1kx_aQz!+4Re+JMeR&O{#QtJn*G= zqg8+L?#imaVlT1!@yk~22fhxZ`msp%83?%cL~f4aY>)&HhH zt@?|EDy#mo;SSXw6UCRcEnwL$ef1$>wCW#9`f;fKYkJ_=e<)OC^=FVkWeXl%!dy`O zbHl_OoU8t~WN6M*e{$Zvo%Xdd3#m&iEtCAq@Iu^@eSZ!l2ITXm_99H?ojE*eNH)xXJJxoeaOgTzwB@4h0Xnv_UN z)%NZPeK=I9Wg^4@I8L z#cyQ5Q;IHzn10QpsWXd{q&tUdy%7aeYne!u)!LH;Dy!D@kuIp#S7a#8RcogxacE9f zD?;~o*^0F8IX|&l5wh->MjBULt!JV%t=6|uv}!FHE$)?Dtz!p^)r#LLU|;^z&G7hg z2Nxe#g9aMnBg6DY+C6aT`hBMS~s)M zciqOqQyZ7YXMuO^-i#h%UQZfV1whErO^rPN?8FO`Mm0ctcR%NZUbV{Ym|L+D|BN)N z8UVjIO#$c2|*YM zR0hG0co#sBL5AWS1bv1$4?$XJtGwS0=7jAH-rjFBqY*Eluxp*R)m*@BB8{tppisq; z7wQS;IH7LsW3QfUEyWA3Ti00l_Y=gwBF(CXpw3WDA?P`j2EjP7gEV2X| z2?V$e3_+_9`o+LC(w74P&4&X7_zqJ^KsX6hM!;XgTtI+Zf|!GI1oTaCo&a?B#2~){ zW+BWcW!v&r^?3oMc{cs2PXxDxG_Hz(SM&Rq_~CRti;%Z_K$&M_>so}*-a`jJXiPuUrDA|0EKC-$PHXF?@pw0r&w(I{{q=#z*z1K5B56^yt7r z`=0;~>WxszK{N?e#=$=$T);v0ky>yNKGJCpX58(4A#WpO5t6$WyFX+4drnBp8Pwx| z`wMP2X=3mZOXl)C>S7cZpuJal+?TqFK7X;w7{{7;&45c(61gYjgq zTn^@$95_hxhd7`Ul5As5VtC zf^il~jveD;5u%dsP4o{uXwEa%Ne%+XYRWY|bQ$l!LCiRagIY8WK9e3D zILI>|;2?0EN)E=8KxG_U9_IoMe16t~gHb;_%>mZf9R1dIv%qxpHnQC;(6zrXcej}| zuKK|3HeS<$Ejyl8ur0}6xdpp%qC>&*5tM?pz15yNk^htQ=uohc6M=#)`9IMnHMa{! zluQ`$d)JL-Va$Jj=>9*I7)&OC$}qS|lF;-HZ^a2(VDR$Zv*A8-tXzqS;+R#_ z)o-Gvbd8xvqiZ?YE0-?s$qsY{kAUc+ULNG0B#y&@uEW0qbd8*(p04fQm$Dn$Y~+Lu z_8;tfwoFn<*CP_Bj4u8cF$qoS8vlzHbloCDbLNipiY@tam6&E0_{B@tL`}}Z3&`}j z!ok4K<_5otd8?wULhhu8<=gr3!s^Qt>#pDVFDES6(jzAq`pGP5#O(xU@ir+x$I+C5n%2QNvWG7efzaRCQYrf9*zBQi8+ zICxlVqjBVVvk;to&i&_k?s&3w&9`Uv#^$EKIl;jogiO2h>3HGtW_OeCu63LcyyWqL znXwPeV@b2BIoSW3rX1Y=jmAOFBxM{Nn&!ZPcL#_A>P1H^>Cu6MvC{w!_9v<2-~$O% z#zEjz7jQ6Zsumo)BtvtC1B8;pX1fL0u09_0cC%e{1fTSY3aB+r%v*KA4w4t$jpdRYQyItfDJOie*pGLr_vezI3C2$yF&fRM5Z z1c7>iP<<8v!pzwK2&P#oLD)(Hm4T4+cNc)r>31zaSWkxL1PG?QKmGZ4@=CK1T=x~w~bX|U(7SQsexdmxf^%-Hp zY)wH}Gn)p&ak5t~2)E}sfRMZh1c5r2uR8|-Vc|Rggo$%hf?y_r%0S3J*99Q-nyUo} z+sM$I00FtZX>(xeeoo+x2?@8RdSDPLdb}Lb#GGfI6CijZ#D5I;=Y{MqGq_?sPjkZg zwcRVfx%|o8ku<9sgsJm11!40%8VKjfUb!I5TIc|RWdjHTbu!P-2S5m12!JqczDf`d zl0ao3lvv;b5JDGd0fL1L%^467;>Xp~?Z%V&@tFG8)3pK6S z@P)LBok;e|t=I*N#fq)*buy2dlZwT!1F}!%J4Zwhpx!{Rk`5iF^4%8$_1bii%6c6} z0+rS4u|+PZ*YA_HsMnZeacEA|YjFDFQ5}jt=7hlZ3$FE_UxF7c;Fw#)&8 zw0{5$s1y0Oq(cV``Yr=7XuU)w28kq483t#TxB!EqOSQmY=u)RKK)VKyHq;rx3CTVi zw-k)RYcQrcTi%@OVm?k9SA~HmLYBdIYVpE|j~Uln-@3pFpXyic(CHeoe7DR=3_2~- z6oa^BGz@+xd*x!VW~BoL)}sIh)M@-@(xC$e`jr3%fy-55FrEY|!{G9A7hvGCLJJH= zt#BFx-GK$8*Z6GUgyg7d75?ahm*n}gJ&IpxX+BFDSA~H!BO~$LB|lzx{vji=UHwy> zU@m*7a8>llTyUk681z`FDF!1}(lA&^_R7Ve_i6_Wblm|AsFQfFRpKxlFetDZz@Ymo zl^9GWfyywrxyl6?RQy8=41WH@X$bi8oExbSIP7IfgUr(&kReS=MRjC9+W_x#cw4&IuvY)bwI&pTcfgI z83kvok8H#hCYpJu=>4KdQ-1N=8=^nfg-16}Yl(!f!pdGcEHi$jKO(u=2 zI&MG6$XH~_){qx`-ez!h);-|_!}OQeJlhqt94F1H=D>TMrX18G=2~1(Sd_s4~lf&?n#VBUHcaBzbR#W@Zd|LHUbX?ItBzbIlk zCz#x;pLlc5_DI3*3Mc2ZG|wcBtK#5&Mn>WYydGcJ3k6Ta>+u&VJ* z6i(5UgN7+I4*HV4ayf|IP7JI>Z5WB7dCp=)l3XEdU3) z%_=$QMgo;_ux7IhICxHm;v5GZwm8iJLddec`?W^+2efqdC(bsJ*NyKQ@Ed7db-|w8 zqG`dt+CnSXLR-bXatn6c4zXbUzplpX?vsKoL{{U;`x!bLA|t6&`O&0Lhmvi)11MSR zR?#RmPxMFb9o&6q{)e1U<7}yIv-+$z3y1Dl%vF}__)6PUg3ylyDg$BjHWz^Ko(#n~ z5V~*I00dLU+Krd?*g!zY_Wl#J@4$tFd)AZ2Rh; z=@|vnPjSykv#R;>+o366U3Sp;8cO!cfBfbNb`r z8?sx3I=!Zj+p(v%MW|AK?!q<0o^TyWv#R-;x=T~OHt(YGb)M{%%hv<5$d}|*i@~|b zLX`deLQRaea~JK?lZ|$ZgK$7=sTn|P%5Ieq>?487ASklO1rYSxqXh)J$k3dF0B^Qu z9}q&-Z4ls<(}3^IPCzg*ajt*Yv;~|nx6{1r5o5mNg{fH&?|rpC(AM;IDYK5x{tf z<6_dE0|nU*i4NiI8wy??P)R|hf7MVh>R%U7u#XJIISPCZI#0p+&ihI}n{F0j!tVwY z`VGIt@#D{zE{AXAhLOfqQE+wbg}ay9dhtTP=?l*^EL+PWgdFZrtDdfeWd~_iH3c6I zYDz)LLo^DSkiBv#=yX)1K=SRl)=Go|+qdK5Z_0q);<$`-=72!XqW}VL4yi<->R~kq zj6UoF1pXyMaSnm9N1R6hA#^4@#~z{GT{r$0+glv*6B{k>1&kn#t3qJ*`+sLWzgLYH z0z=Bw>U5$yFLdyT%{Q>aTW%L=Ry6{jk7$a3&ruoz0@*7UfnFy>1SFrsG>sq#;Ll-x zK>&X2V;$+z0fhV~01z^cssy3-F*P7eI_3fpQpr%91EJb+r$M;+KX+Zr-#sis;EcS% zL%fUeLh^#KraWtoaN|hhsz8`t`YHE%U;|zlJ2gje&$N4Hq3ww= z#4KzoP-pVSes8$rq*>JJ<6gjIY2#wCtKFFz#Ma`4O9KtTgS-B?sBBsNtaR6&G-@j10v& z4&1Iff8f6VJF47tvRN=KEorK4`y?j*DE<380X<0LsyIj}@{}8It;Gw~`joJA`RlY< z_fCVPAjSxBK%L1?Bt1HCU`+!!xO`0| z2YIin;UN6F3piLyhTNc#p6H@No-M=fMBrhZ{ zs_fT)*j{t7yJFs|4&AvB(v@(p&I`H%C^;%>FDLxI;*lj}sT<#iG^?6~g?BY2VeefU z3Af2!xg>me;6Orf1WW>TGT-4IK*E*>013(WRFZIx1S%t;%6%7*F!;U}BpfG0bAkjE zcx%y<8cR4K?OG8NXL~;){?hoM>jC8+I6*??GEWo7;C1;*rm1P?Vvd-Fwo~7R%;@)q z3n$I0CSlbBO-VTNfJVYovR5t%UQZlI2n>cvpibv|JOoHEKL$ux{ZJ(dX(Uh?3AG=& zfP@i`v>@RE8JZI$qAk;YZc=PUHt zp3$#eFdY~{MrG8qyoQ- zkKQ|iK%LH)cnN?o?lk~{;iXCtmXknbAiRI+0ucCDT7ay8N2M|(MfoBBjY`**(0EEf!01$?~Q3=9&5~vIWkGC!Wq4irWKv+SB z=ENBxx%rz#MIQdi3CZEPQOaDhIBz<-H{cU#Tonkdrd}!av8aw0I!;>betz;wv(S6{ zr(S-KZ*z^`ISGR4ou(ixeMbY~0NE=Sgr7e+fMDGTfwJo_gaAPCmEU(AYhFL@c!dZpBXd>`<}6?`aj=Wng?%f9m^HZjde=7Ux@i1}e7ZN0k*DK?0Rk?4FM!S56`*nq;XY;?)3&MSG{N*Ubxlb zo%u`;4~x)Z%&f2lv5hV1q*>J^V!w?Nyw5F!nsgIY(2N5<=;L-pPD_(OZKL7oVqrUpY~5U!#iT%}E_bj8Vh zyA5!2L%7h~5kgsm28M)1L=R}za}wDr7ldR_2M~O(gCI~R^Djx44j}aM1VCu+E-HaP zz33Jgln37zHpGR*MHr%+gvLb-(c3iW|3w3wcx&9&2ok6agj9FYIZeNhx1fg>AjEn& z4MJLtah4~)Uoi{810QkU$B7G)$U5Ugz+uw3DiAz-7Easq&d(zJ8uaA4Znh6Ew7MF6 zdn)&U%jxMP2<<&J1tG?h2Euf*S1t&hvpRsl-v>dUPUb(7E*(I~l@$P?gO^GW#*si} zAYAlv0SKkCXaT~=EKY-fZ_PHZkgmROOI?SNti+cm633ZB%$dkp;C4&NEn}83leOb z?fTaKxbD|pT_|(?_&(WsFw+ObBaT80PJ{f05DTd^?)6;1NQTO0o##NC1B4; zpfbROTw)TM0yZg^7J%I&Lv!LPT!abP0TbVsXxkd+7V}mG*o9}^mrqzR#3GEZTJ!t% zW?x>&&;9gq;gBJGB577NV0&|G3fS%3G{Cav5%Cb_!Gu{AO<~%AXcufM8QPAc)7f_J&ofZ^4AwzSTf^3d2Ox!JaJ3+yNg<&UajUK`a z56%VVdc&8s2rYX&e4d^-g#Vc|tD1s;y)~uap*M|!+A60&kvNu#Q{ zDwSVTuA1hjaiu4F<(^$)3yEA+`g(m7<3YH>0${EHst%B@9H^>R2%xHP0hLsBAc4xL zT3WybR6QU=ac*t5ML}_BPEds`mG%|=rza_zBA|GwhhcD!E!g z0+n&~fh3{nWlNJHVh+x6wXlfuT%|pU%a|U)2}idq{Wxm?=4xL~^A8PD%&$q~s<^6< zY)W1n_Ps@zIOk*EU4^SygoKR~|5~24Fkh#rIA+yc4J)cCSM!R}xY|SZ%H^tjNs%kb zYu+gLv!Yog_0u-A1>?>PTvW5v@>5No8GNAS30pLu!NYmDzqZc zv}(S+U0Ggu7qIfsPs7ifg^L*}9zhAGxT&OB)o7hAp($E#O3=_MQc~P27p*fo2eeRS zN3{Aij}D`uHHviSfYuZpfL3Zrl@Mepr3QlDrCb2PVlouxAoxs%<`e|B>k0Aus&-`& zzoy4@|Kg%uoKDPJb+wMxXkjJi)SEx#MrE zqSb44AK+9lvkXwLCLfjcx|IYfJ80)D?SgvkR9eizxq4kshURp=ep$w?g%8@p&dr>f z+Ssd%69?^09gp|*U6$W0{5rP&@ohba@PftTQuXQuTbf&tW>sS_p^T;&tSLjo;5gYU z7lT?AL=38az0kJm2nKoWHzL6mEdR0q15e8X42&zQl7XEhP#FW?m2&|DUCU{~z(z7O zCm49N%v$nhOi7F2J>+yqFkZnreBgG8O}W#}*~>e@!10{>vVZTNl^5#dxLChshnZ%f z@3fY)e9-{DFKJfA3f2kx3f7&zWCiOHS;1OF8dVL}jq;j;=0-6;xuCx1t!R46E>pF2HIn8H#hKmh6?pp*evS zLf$jIFP>^FT-?0!QREWa5*G5A*==d#VA8m%>w!`CN;D72R^1}({(Vwnu1e`<;ZAG! zCE?p%m=}{~RTFTllBNV?sZ1lF64@)4fZwW#1W4|Uq^%+ZeEFUOXbtOE(wPGSt*ZeD ze5foMuVxLa=KHFZ19sBZuxeFN3D%D!P#IX}DlP!atE!lTb71wa>O5EvFOTthHNh-g zI+3mNl5h;xrV+Ec4&Q0sK^j*D*7CA#{;3g}-6C|EU3tc=^8UQAyU?)1#~N0%yeG}7 z2CGpuO~L9{jRw{jvR5uxk9f6+4$1pK!|DjWny8t=Ybsvh|lQjjd~BuUxj~ z)^uRYyC#J#XcbHF6G!2|R+pLpTeJLBQgD<6Dx<*1-vty5@YjNZePn1(QGmC!UHBdp zAHPRuUphDK@~SE3t-4%W*3`6If2>I>*U4nB+;Uw~M=V##ySHN^NV$G__cn7G>ow`o zp^eI&4QYnpEUKPU9Y-2STP-dG4BpI%xdZlWh!pa@TQ^gN}7H<-k~n#=%UoS1t$n z>xmqcM+oI<5*-m``#@4qTuA7kcB$Vbj$G-6kZo?%C1j9Z=j-c--0)x7{=oL2P1brq zwKu3Mri%%43k=GEmxc|YA(26GA;!2MOikM^5mDl&o@_th15mqFqyFiQe;7)l@hY=h zU{Ln2(S{f>IQUXXcHGYn5=*z1_2GIW{=k{M?%$IZBnLf73o?cPZ=po-3g0N+ zE+j#3Y?n4Z$<3xXUP#BcQf<3M$!$N{MEYhcSzj~|3zhGSfz9HLL-ZXCVfuEu9K^)p z2%+$Z$f*8?VOKQ&0p;4+lKagqTk3jFq(u#qx8i)hOOA4?e9 z(gti3Oxcu}FslJz!o&vJn-JAd96Drz^_B_~f*S%E1U3BT7^tZU6&tZlNXj6Y$ReRw zBOrx5jkGu61sOVILb5lhA0;H*fik#2GH?Y6>jKy&SZ*sZAvpjrVS0e}CJb%NCLtK9 zFyY6>Kn6cFb{z@+9NUCccO{3TavYFCVNQD!K9ZqBBm`zxVZt*ggPSA+SCFucXPbZ& znXsA%Ojy8cZ^Gy%Y!a;YIfatLQCt%sg8@xkM?#~fY!i|_l#o!PDUd?xrrMj3r5W3V z7*7=>q(d1zCKlzX)s-((FT5Lc%Bk$Y8MGIucqm zXOoaxNr?&dn*%9SZLYlu-YwWBAp6jjnBdU@$lwjhz!fAMA(=oVmM1dydj}weHXXDlp?XKQ3BeUqnBdb9$RK}5*O~Bu zWCD@E*H>b~6)1%hBn2%=*c8Y%LDyJ?2`d5t6XpcE&V=YrY!WP-5)(o?0V#Cpq&*4s zI634AFfCd79KQW)4>dlK69V4D!rTm=bS z4r9yS1KR}DOo<5-e*jDv`GfW(1ovf=5K~132|;~<3|jPcoe9PI zu}w(gm6(vHACQ7uKkZGpLxv8Kz*kja!UZUUBP0V?EM+GLvrS0xQDVaMV8Dd&!P=Yf zV+fmsR6E2!J02u^^xQ>K!{n;k?HdSIm;r>7hIs0pG!ZR{-hy-snC+3?_24_hI zt{`D`DBFbKqDo9y5DJ)(6so-mabau{EdDAEM+3ru40?sRj)WR|wh1ZKm6%Xk52R2) zue}NBWatnH$$|6ZjTNOjsEXm@qe7dlNx#MRKp=%u1GP87BZ6&$Rm}q48z_SZBm-BFu!m#xQ%?7ba2=rBALY+ZC3Y7+FZ$j=!wh2i! zRUD2`B#^;Nl7TBoI7l*qNC>W_#Du?~6xK&-Z^E=Fwh1Y%RG9E{6kx)zDA$qDKAKH} zrJNEI_-G)7n$g;uP{_bG!MC;w6LJ`U3_g(zTtUJqk_kkDrLYnc_CqObH)wCd{1~k6nYQWo&;_L+XVDU z#o@?*1du_w5w0`gJ;?+jA@!CL5}rUQq>&V~Bw^o3wh1YhRhY1CBw)hok*+f#@h3J3 z$)A;&VEhS4LI0EXB(xsIHX$ZMg$a#D0U6X7 zN%&zLn}k%W3KIgy0U0zK=Q<4|mnuv+3uSQd zXV;mqU_9FdouXxnr15|WW5;Vx!hrv=NwB1=FrnA~fDGFI&vho0p1?LC&{N6bsK5ju zg=`bFH{mfEIz$4pU*afPwzv*uaEfH$ikmtsC$dfO&920Rxf1~sCQsDfgu#>8B=Cp~ zU5N={lYk7mPjVdzRexcd5d1;OIib`qKnnSO(cXkNWatnH-u7iLB_=$8GPpuAa0Lk) zer21Grf3y)*{^^JzyGSe2_q)6Nl0;5K|=IoAcK&}t|Ot&6t)R`ZY77KN>hLoicitr z1oRu*1f*t)`Vz|EF3G?ZB>Y7(ffn#gZ$ zv_;F`ffO42uDuB*XR}R6wL`4rIw9|DAOp|Yt~22x$pj+7a$N}tN1+tVBn2%O@RrVD zn~?NG#o=hy9KeK$b6jUa-??lOlAkLvq0?L-1!1oCBvhQoHo^Cq3KNRW12V`n&vho; zBAGxW_Z9(E?|?8W}oNDIw$mA0Hn}i zf%YW$FJzmLa$kiB114-(?m833uV9-H zTv~|<2`hjUB3EcnLf}d^38`gOn9vM=7=!jo&N?eyXF|?ZY!fWsD>30Sl)`h8f|ewl zB}0cu@GYalgoCR96aHG|IunxqV4J`fRbs-}KY$d5{GmMwy;ieHNGYzug!Zd}4EWWq zGok1jF%w*()USOkMKURZ5b72Y8__=^G9oU4_Kk_T*8t;3YrYwOF55RIer?P4m7bFS z#0LZM+Y-rlvRXO&0m5;szE&JRo&nLupH_^F-y0#+g*I%TwZO1flVRg8*mMgF@~{oN zM^F}oP>1-a{(A9CG|5QQGBV6Row&eVrv>!{f<9(slqy@MC!c?K%9?c$m9-?rtDWvVS8$|AG<*IOQZn9UhyZz9>`N3I&`VKh;{UV!zVK3Q4u?O-LAvEPz|8b4a(}EyRlMAfvwI+92KG$YSPmrewCG}|i$KJ-U zrwz8SH9_|4GkiRxp7*P50W{f48!1B*gpiecL<@p65!14Ax-E({5qlDYX|kEeO)2>Wb)wueP1$YHd}ZN&C0GPkX(5$Iv9t zHa7dZe6rbh+Xjg9iVWEm?3doo_SCna#8WE!1-1jjUbu~-G~_9oaVULK{r?WXtI$uQcx4yX65eDf*?)o zLB)3{(S-CQ{!821>||?_Tv(zBmHmL7fF=iMBZV|++cw9zot0m3A80|4CUIF40|!?= z%lYn9pvmT++?U@(=?qPB{KaNJ)jk)>{CfWrB#xB~*%j=U+{O0PYCm>?bN;-$08i)s zMNt~^6rr3qOP49aouCClo?3!tZu_A`4c>DXr6-7eOUL?yAI>y0JoVqr*2G)720~@O z+-^XV^|X<~n&8dK-J%6Snuy?9xx%{@Xkrf%|D|m$_OLYxESVYm_4fdp{7oAvq{-SJ zKX4~a1^KtMAV`zLL;UyU{XN-Sb&mo~2EXi|HYNTlLz66KHv8Ty$W6G+*-wYWc}#}v z3igXy*q)kJk@17<=e7Wz&N5S!hCD^ddG~hO*UEf^76f^ky2R2l$-fMbER>!g_S4o4 zpW?CoIm6THd)b;KpO0UsOSCKe*>EAp^X&M2S=`yBu@*-0BIR44YaJ);G&H9@HC0mYiIw$DTp z@E+f4+3Y`u#JNp|>&-Jg8e*4 z*`E5ImDD+veYc~4r<0CQlxBN+f0vmS#PYQ6IY0gtEhv*Z-vPT?`WRc2z*LDQRQ3xT z12kE9RIw&j?ldikr3uD3+c8Q{nP|dbzs_;CCdr2-no!xVbR5uRBW-^6 z>}$?)H$AOf;Zq7UF@MbHmp0gsac%g5XacdXJ1Lv}JCHaR$dFyZewH(APmz7S0$l4$ zKMi;~<}^iV$WvsxTISlcZsu*YAjs3c>oyji+PF0Tm=*-r`MY*+Mh{`IU-T?nlb8#V zI;XOq`z)ZztTRe9v29lF2rUTG#2$psQhI_l!5izmU;P|g6Wun6CRFx)&HlssY-&`#G2YoB~aH)hf4RZpBIr_MZ|>Aof#M%4YutB+eN! zWLL27eu3>Ne^KHobG+A*`fhL72j=WG$ILBS41woqBt$pm(ldYwA?@N@PAWdGkuCeg% zCy2rRL!t@9zVAWV>|ce%NhL#e1^b^bvpu!!mv~BL|M_LW)8UsXN`vg9yC(+u6)^uv z3xYfi^GVsZyj6YvHZ2J96s37K{i#m`qt5ePWozPXk!V6?-|H%%$&@RKG{Kvd`-c_; zX(EDa<=)YPKut(b;=i=5{57^Fx_uH&sO%TH257S6ssc@3&F^30htu^e=V?KZCV9ID zlzBF`t|iwsN>7j`pS_0;e$b*6gZ;Zi6Nvr5KV-9i5fbMp8L}(be}A3rX_~aosq81t%+rg zq|T}AyWIdZnUtnL6OlnHXQl-~n%IM0(SjgN>_If@#jW&BwkB!EB$`m!FK`pkWZ?}3 zn!L!!$hcRs4u6^!1ZlG2b4IEAFLLqOZc=)JG)eDy=+|12cV zK{8}lu>a;3+f#m{#8WE!4{iaT8gEgQhS*2%8eQMh>zH{ZEeP^d_uZmwK?QU2S7A?^MxE!l!`8$qJ;zbm|8yJBWc+O?U-B+n zljPl!I-#C^S&qDCjmT29b{AWe#vteIvpmf$__QhI_k>Au9P@7szz z<8yr1h$ayGF?(dQe-aXB9~rVM*ne@4?Phn5>2S==Y9xiGV6f?O;XQ$Sw^*~YB@p+f;2JCLdmgXd@Sf8 zr6)*}sN{PS{R0m&)`Tw+O(6D7f6He77$lB`4A~XzKYhgZG-b2IQ!4v69s!>I_=uu3 z#6GS)bM)I?i)cZRrwAd_(c6eWLkogD#m{)Ozc6>V2nlU-f5O%T9g=85W&ibKK$B6A z6>5Ud#+ztC3{7l7_h~^4O)@#}7ktXr#A?5v1wPx8{VAZyv?q!+LFivv5L*+3KGK5N zny|KWL=%X8?@hAVKLm-h>!~P?E7*VdjO}U65lNj>*}wV>@HG6H0#9eW)Lqg2;c1yi z3xYf?e9`Sim4e0jR9X<|>F6l~J`O*`IPZV9vNcIMAkl=%{&Op!$#AOzO~ksha(~i- zAWiH+w`oD3Cbo?==g;?otx0l0*hWpH6X>y8a0 zR_QYvRQAul1w8HhR)MGJVXckEk?YOVX+e;u!O7>`f1c;gAEX6Ao+5P3w`cao3{T&@ zV{76qUDKwX_aD3iG%>zYqKR#@aw};;kS6w^E3_b36TGp`aXH?zHL+~ZjQvmPfF|S9 z6=*UDA=B=BI{q(O5TwcF&F&`OUF$e2EeO&ic*)}fGh-hz>f|ud1Y$q)5~cf$b^(FBw1hT;ItLz_5FLP~a&-C^>AlTflF$Ajnf(un&5>@%v~& zkf#Wt;FCU40U{){?Zrp7Cf)}nno!xl^AXS_`lB*UY(y@l1+g^27+;_TF*M19{Vbo^ zn)q&&XhJ>jr+)%88S_c8CJ1e#1+g_j=rJvbtqE&8Ks15aPueS+{T-hHan^oz9s8Fu z*q)kFB%V^w`^PeXVRy?=;Av{jSHj%W_sqZ0f*?;XoZRE(_G3xjLJI;t)%Py8ec@il z@%$-rNBGU6(ECf1HcK?2vVQ})e<_+=fks1&-WV65kFD$bBXUPx2z~ojQP%n=#&{7e z2+~CC*UFut1%aB_Hr9FH-JPvTn)G-`W&gDspvfpV1)8`cWLm4Q!Ed4kL7Lp~N4hc< zH<|C#f*?)qU3%W)?m#cbJ-)w*CJ_698)UP;#T^i5mAfd8E7tnXd9XcA-6pAXD*J~# zfMIv`P~fR4?@xdJoxIZgKUxsvX>g&tISTyGi{C{Hf;>g0Ci`a`2xPGT(37o+b)!TR zD*IPG0Zqa^6=-57avm)R(!?H=N(%xt$&~%iUTjT*w@5Uhvj5x*&}6um0!`j!WN@K+ zKmJcz5Tr@2R~d-|I-KNg(}EyPbX|U(7SQq|qfYi@5jBC>w``Kl{)Q}oILorQj{Q?v z*`6kEmv~BLe}7hB*d4Me@D#bdX>(xeer_x+2=bISCM4XN>cMZP1wo!7Q$>%LBbqQg zy_=1#N$Ng{CRFw>W&>)V-w&A#_vve{pk z0}v-UhwIoso|Elq%npgCRQC7g1cu!vrvgtALj1UTy4{JiAjng^NYE;$7r&Vn1bK=O zvb6pym~nsqX0A*$IUv!5%Kq70fF^x&DbvI@=bugsVrXIuI!Fs*Xp+hG{+rxvO>}07 zCRFwx)1d19oy63 zza^eh+28#gFzgoJDeyEneetLcMIUn`XhD#tf$bMu>p#B)pF#@)JO~ksha=+1nAWiH+`)EO+Cbo@rz5gOFTN5Om3sKp>lNZn= zIQt&WzmygPX)^F`M&kSvd$|j=AV`z#g?=h}sBvz__5Q|uZ1$7)lRC+q z{pI-pac1Xp9s38qXM37*NK)ri_IG>_47=&~3Oq%-29Gw>8Nm&u1wo!B`)u4&Fv^Wz zOACTLMW#7h-kj^gnDbxC&(_3rSfUA){bTt7O}gb*q6s1L7g`Xci9N_d3j#GEJ&FI) zwx?uD8B*fjdJBf;9P5zjB98 z*ARpK^#$4NTaU_Se{n%ToEZgO$Nt}i*q&OBNj#;pzoif`?8b!@c&aWjHL-21^ZvsknP{>@q6wA#t3?1!!iy--#F~+jcNpk%g1HWiOW&dIcK$HF@6l;Re@3bJc zCI}s+1+g_@Z7WK$*$+N{I6)@+b4mi@{94j=?C&ha_SAZYj30cqXI&{^*mX)N@N`0O z(>M2~d+>v3L6E1xEg!!?d5iJMv>?#a9krS^h&{rX-yYYoHA%iF(S&;5->U;OX`@r1 ziCA}5E|C@lX<`rBObY@vv2CpL{!JgYCZ_8WO{naj^#L^L>!U!E2N@ZQEZG|J(`iAF zCO&U7xH{{ea0h8YkS2!dFRyvFE6AAhFDcDtKjoxs_Ggv`#F!Au{GgONHn3cf3h5)Nw0DWGvamJN*9s3(A zuszk?ka$XEe|ZI9*wrg2@HF|{*H=(CQU0U(8P}MP+AbAi9Kj7EeO=awz1g1REe#L<*Y;#D*MMO z0h)BHq(Bq=4eA3DefeK#L69Z|&t!1LE1cjgv>-?m_p)8?ox1#0C{*CJ6nH7R1&BpaJsdb&X6s zeIoIc%Km~Hz_82LP~@p8W9`OEdwSD?*q)Z=lW0KKYU2{oSML}OV?E3DMHA`es@|B*n_Wr-$K_Se+{ zG^tZdnI<+O2hoDqnpnAHS`b5%OxQnOo2^O8HHjuv_V?BXG-*>?fhH}?>5q$V$Zkob z1woqB={0rSjy<(4n`uFiCRNJMUASi069)TJ>af{Qy-PI7oc+;t0CD2#xQ_iLb=jU; zZc03*vOlvfFzk|b6?iIQjCKdnf*?=Dpz8btS`g%^7^Gv&`M1_%Yrvi~0&QnV2}&ziZk8ZUij| z(qwL@dD$bze8;EIf*?(%W<9+3)q2)vz9uzbv+sLHHv2y{0K|!D;5zmfHe`F6bW7qX zmHnv=fngVIsK8Ut&l!nrALO!hqy<5qqK_GgCpwnp$I*fyPcJNRH~o>w`cAHmjo6xa zUzKP=Wq)}iK$Gf?6lfwIrL0^iEeO=awpqE^v>-?mdyx1qZ95Ra)+9};36=dF0e~h= z0~BcTYW(Mngk076p|l`KlV>&0E}EM3!n~Fi1Zk4{Z3Z`QLv_YIzVVIO?0ehSgflYU2{WDXd1K~90EV!ajJ-If*vdAchjBz^@g8on5o502N{r}@PL?|k26iN0iq@v~C8RJ zB!se+Y!xY~WY4~nU6Y#0UXf(qvy*M?TW|i4F{h9F8t0tp{vKcc^LWgCJbL8m+}Ay? z`+PlL&wJ<0ZHB~2>I0{VTQkeZw&8+EoRqG6)^TZWeM;|#JJWkV@EPJneeX|kCXnOn z{P%i4u_L{v+;c%qvArMJk&w1=M-eq;_VhVf=gl&y8!m`c)4(xL9Bafla5Hg1q?$5C z^Kaf7v!8N}+tG>6NrBK0vDf`IiqDup8~E&whMmN4@@tc`gKcMFb~zc3ppRvzsnA0T)E#WcaeRm+dXBWt(t8Bu>1u zds^F>n^Agywky5&4HqI#)c5{GR{}YsT>oD0$GOpKT2P!n@wvYFZiKWexrwN$LT{JH zRLJOv3nJCD`x6~*QRnttFfNExQ^ic2+f&Nx{Vkp8oVYI+=p5VoD>@T6vFI$46U93J z09+7>6J_Jd*~PdZ8YlE;dn8@xoG@zyoM3x@cNYRDHeEz;lJxCN;@hV!xN*235-0B7 z^{snfXvrnxf=Hb7EIrxSx94YyA5QN|?|t*668HZ2t^{(ty8gZ1U($_U)38WEO|jSg zIo$|pSLi09rVkdDGIv{ETE^mnh&7Ej@|tQ`n+w7Pk!qT}W^P!eowR3qH*}|S61Yyl z3AXnWx)V65(_I87#ckXd7ewNuI4A-aMB=14NckJL9qvKrBv0*ie|rxCCvAF&;AEM_ zYxbjW2hIlbi4oc{;H@dl<(x4+LPY<$xBPz`+hwMlsfPK;_uHiQxFAwZWt~mD=3Oqu1>%B8HB~5E z_T(<*y1&+)&WXI(&xx=1m%0-;spT$)lV6*h?S%^>aZ(&K4;Mt^gnr%M-@9+m_H|$XObTetjl>0!IC;F%&a3gn9BC3Rh{VZ(YBtgPhkv5@;iNwF z-uGHk;@%(Khd_>JpTF1p3;NP)YPDKWQ*7^t^d+QSs;`KeGG*&9`(|#I+TwypHTC+h zoh;<_SJodFM5?KxIl}Y{D80Y3ADt7~3IQkB>wa`U0w>k`iQxqGem7hYiId`>FkBFg z6MFCO@t|{(r}mzIy$6AlrXC_V8Rv5QUbzS>Za6N8#7QoHS*mm3tTY}MMB*gPc4tB` z_mR^30sZN{AG@-|z3<(hKu*8@f3Nq$2heL88!gZ|w)dwDAf){RrQL{O7#;V%ich{B zMf*%z^Gb8ernen{5dx{EidXJ~6aQmaD6WTU*5WV*U<4WB7LkAJaaUb;edVls{dQHt232KV%{fUDKX@5g$m#Fu-r)86^ z8@!aZ8jKMFsiua5Dls=!nQ^0VL8O|7ecKyqb4y0~8;!UjbWXTr0VmkrpFf1aNu?o} z(^J>`9dSVq!wG4BLTQ(%_nBwQnWoOs(q_XkLLk*NY-63UcH?z8FI*6*rV4#0e|t>1?l1A8 zbHdCO=p5VobG!(gRPe%_p1R&=aX}1Kc|hs?s8MuI0_O`j!S?>FQ3OuPj>4Rty56_P1(7%@?)^Yq5RDUh@2?$A z=R~$xzzMeZmyRZIQfssbPG&mZ{%QTFHP;IlMB-%hqGnzd9-ouW!v&Ez*WrCVwdw;YKA??>F?UMCA!^j$~Gf1!R zgAoF$riwquoiwa8=ZOm<)l|_OJDSm6?=SGBbK)K)-~`+IA-)7oO8H_=PhIcZ;({og z{Ay!=To8>Ddhf6FqjOTA_PQVKN8qHopJ+}PrW-DZ&I!YW;ezO#(6&Ki>AjzlP~zV2 zF_u6MH}>!Ke!w_-O~VoeI>+|D_c%h@g(&S3^}gI?`K4nQpR#qwVT3@cY0A?lr;hp6 z;rii%NHtAf*R=JBVA^MNhx^kxk@s-;{R|tn_ow(1IQfCgR9)}4^%ud3Qmk^;7Z*h0 zq&SGI^u+OWPV(#ooM5l}k>d%R7>~!C9*GluhA}rQ)sl0=1(9@OUX4i}KR%P4i3=ie zvV6-6nfFE=%Ip390cv{R5pkmay5A*$K#oJe-|PLc6X-Qfu@cl2+xtT&5Ym2v(k@Z& zGwu)9y=t|AtvvxF1X4{4?wW+L3w1enTo9?I3Vj#!y+^s{pB+f&#LGs&3AXnq1`;^= zhRc+s^Wu(d6)1v};-FEuAQ~t1>wersIwyt>0#2~KKYt>DlS&gYr$^$XY5mus;Q_6= zj<_I_PMU-*Ew~z(BMrs{kvQqL^s{$7_5J-mljyx)(5l3}?=p!%j@_ic*ZX58(`y>o zK~Pg{?+=_zNc#awyF|TT@S_Z8{^+E%#$=2TNHtBlU#GwzrZm?b7euP5qB*!%4=KGr zJ&4YUIVa!*+xz2#2%LPvWlGX{aT_-a62VDvkQXk9#tFUmmrS8^lH6Xv3AXp=Od)Vm zVG8E-NSydIe!Xr-U>lCb1(9@eRiEMd?a7q};etqD_^er6r*nckjL>AfH3RN~&} zrxM7qp8EHCf5bF;P2JlFYKrZBk7Y&WX%gzzMeZ{elUcyu)Qm(s^+kHwqTV$*(pZf(xQ>qNeww zLg<`W*$Ozp_WrC80w-ldFsDc7gkkJ)K@^?*+5&MwbWUhn*Xi`$XNq43slVrUoK7Ie zYWm;n{b4icHRbFDHO2OR?-_)&Z=$qI)cgJ&n1X9N%W#!vV1z)bDc4=M;Br+{t`jbZ zRMP@kMW)&OEXr%!Ni*r37&BB}>iIYY{j{Y3py*6iy3nJ-cO5F8(Z&Ei({c%AgPOfDf z7_+hM2g-9GuCwXA@6IAl)c1b-*#vT$&;EP8KPZ%5(*oh^IBf6t2qmO_6{TIG-VZBt z>gS^?5p2a!j1WjQO&(l}nG#c$<8VQwnkw|Y>-c@jJ%2zLofGr60-a-f-#d)JNg*y% zlFo}evTm3NPKty2;eu$K(C_)f=g>Kk3ttCedwNe$c8&;6 zKBoU<7Yxji`r?8}oOqS*6Wysl?L9u{aC+~{_!9SiyKn+Ijl=(5@AsceuW5ns8i(!u zE^`TK=cBYs)ceUUpVpZa?q$o(6;adVF$PS^%2J#IE{If9MRSCm%cS)F*m-nLVx86X z{?K^@PM+X0CF#7ljcd;n!AWtDJ1&UE3BC7c&!=V|`YO zeJH&@CW6jMpqqdb>~()&1c8$WxJ*epFK*)+5#l)c)yCa%K@?8Z^#1fnIww}01e{=d ze|#i?lTWxz>6|c3vq;gLFpL*2h|URZ>kvinee>e?g4Oqaizos)=23sI_j@j)*EF`B zpr+W~=NA#u&PHjMsP~i0{TQz6$Z$V#L8Nam#6mWv= zeZOb|C+~2Xk~rBjLC&_UWy3X!7Qx9w*Dun`o~30&a6u$aT*DJbt(ojZ`P?3xCG_6U zE7pnn-fyymK#u8>zt{U+W9T&vYb~fLw)Y)l2x*^2X_u(?nQWg@Bg&m;zvF^PIxpz+ z-?}MPD{@vb7$J~qs?awVLHpdEVX<^hl3fLyV0*uJEP<1oxJ*epFYd_7v6#~%aZ()A z2^U1;gnrLIX(^qPuxjH2*VJl=pr+W~Z?~L~b_PnjM7^(g*v_SuvEzGO5Jl%+f!7$W@p6n1NHtZ=^sLof z%KQ8Mljxk7PZDr~?fouE1WxjCnUZu~+{WdSFsDc1umALoKRuafDT>1BU-)R-Sre0G7 zHO2OR>s5rbB`EEZ_WrN!4K9eTa|_OL6-EgE?=|hSn$Ahe2mvS9-gj9|;3OB9DP8As zw)ASu>Crinvv#;3Iw!Qx=pM6%&IvP3zzMeZ2d*J-@&K19iId10As&b0rpjup5y6Ss z#hJIS%gnj%xF8ZIL$+G`WX+sPx#w@Vmfrh;Atmm8leGkL^w<8q-tVxEUQ@#WK~1r} z-(nph?ZYT-QN8~H7ev>28_s+kMhK*u(wtnm^-QL75;ju63AXq7WCADIxJ*epS7sw; zf8v7ZoXA=0WYL_^dVj=vIw!G%1e{=d-(x+2le@S~Nt|4NGhlPXmZ`ET>oKQC;$%Vd zwpDsat+>v(Ad*h1va^cTPNns}#Rhusr%Whu?^oMEAV+V*-|Kywjr5utdJAfb?foVj z32E;~X^ZH6z4WKJAW}`0&C!xG-G~tasiw*xbILt`*G+Uz@`U%d*xq;CMBwB!E>n`u zi+le&E{M*FoVD5{niE>@58F)VBzc@bC)nQay_vwtOx2s;>BP;m@a@-7TJP7{LhpTMXo-8@XbXXyGF$#$@3+}Xuc`YeK~1r} z-(V{t?L8>%67~M;^U=M-C)VK};(|yuHEh0C#-25i)!d2^0;#4mPex32F#1Y+R&yJj z6S>;g`|Y<8I602Xl%(@>BP#uR75*6)MB;=Qt_*6vO#~+w6d$HY?fpU9>6~!m1vUeanjUh)ZlhUUP(Dz5J@KszV?j_?J}D39$&2; z^xiKhzGqgy)@QJTKn}Cx@AZDmo%EW@CJSnc?frT?32E;@X_u(?8CjE)wN4CV@8N<- zHI?ot)#AW<7q03~j1WjQWf%)1@2_1b>$lFk=$sS??}f0}{dT(uoMhlKCF#8Qy8j** zMB=14sPQgQoT%&l{=4a%garz8g6;h-y9u1+<1!_2av<>2#}Kd9vU0mIr$^#s^vi%X zt(zIk9B@G-o#YS5%sI2_14Sp*_t1OaYcS$OeeajwLm;OJrEIPIz+3%aA9&l}Z?fMA zKYzcVkiHcdh7mwT8T;xm48#9V2ueZVwx)aOH8meCs42Gh&Gr(~-m(W%9#T!2f>%L5 zm-(@`a6zP+o;$R$DAC7-Gu(@riBwbOWJT%F4k?uDzEcXF6ZeS%PO!b-I)%WA1eYn1 zlV6*heS-@kaZ(&)nIeW0G?Vf-ZtJs;&PkrywLX`91Ws~snUXkZlpL14epD4%>3x{f zBXJVBqG;H$n$2W(xFC{FLiR_dZ7x@nvesw3pWgdZt%DG#Zp43q3P;rsQBYq%g%O)oumd?7Jz!s#Et%tWdw!!TVAHo1_2 zQ@C>LaFEVPakimicQYGzy*;wQJ#XFH9shh6E*kzJrB`2kqfU8 z*y}!jh`>oUE>jXG{+Bzu9PMt&{lo>4IQinZHEY)NYf|e&A~?D6Go^IjkbH_CRys`Y zec2eK6ZO}9ox=ojKA@EUM(j!Ud6Pst7t( z)`HVJf|-fZ`(e*+tUIQh5x3bKrE}utE8qm%`%R7#IN6WOR1GKWQ(O>@6NO=z9u>!l zn%?i4O6SDNPrwPb_Z?FSoSepGO6P=OzT<-EoG^@4s%TDVTLlTd_hXMfQa%@_zW4tl zkt0Vb|Bc?SlcuJomr?%2@8UE{Bh+-I1jDqtnqI&K(Q9hWl}W?QMDG3Is|icNZ0|QXM&M)*E>k)ua`quEh|Y&hMH|=Y)A6-~`+I?b8XI z9LHr!;^aWD++kLms!BiOf=HY!p4&e6$iS&w^K=oM$V%UA*|NGD<+Wki40`Xo-!5_Q zeU+lb^fX{ z5uChGyUy>NN#}&QBG3u8_uFL>ILW|eO5!B9;>q$=+LYto*i^XD-mPbXv~i{g zPKL#~C0a2)l-K*Ej?;TT<$Q^I|09Wr(fid;&}*9fP*78B@0UM8sA=4B4AZ2V zGK^t@;f;K!Gq@m9O>Z3B`oe#M3s-~-BK1DQF!d7pZ=_uJo1Ua|!kiUwg6(~?lLSt- zoDju{@@jkw7ewOZR}3R(4NqcbqHv<-y6<#~&PmuU0VmkrZ+(iui3FD^Nhh&|k;o}PDgTY$uarZtX@Rh&*z3Md z4xy$|*%+otHD#FO)EQ$gXGn2Dq?#sIjVh~H=l_5UBI~@MePPZi%5~r39G#Oqwb%V> z=Lnpv%@M_kVw1C%a6u$al#MHA_0C~tB6FggNg0gWY|hg;DR`o;_nVw2aIznlDM=^c zn|%8Y>t@M4#RZW#c|N4grWVt$v8LxmaMGZ0pZW_z@+sGdPlyvz@5_#qxc8rv$hnPD z{u{kt;R3y;^236fVtfC;TtZD3`jg6KLAqpb7S z$)j_UCwy&-z3v<35ja_SK{O|F_5v=5!pSegD3gboiOvaat*^~RIww{Vfljd3{RS5a zob176O4kX)Jj4ajIboQZ7e#YI+uk8gNWCAHTjJh-Od{txO8IZ}e%VWEYI;UcQ*7^l z%_r0}JRid}rKT0*vM)Lv!3EK4YR$dG1(9{WDBAUDF6Fvk>oT1auT%ji*xom|OyDH( zk~mI&wQ&wEh|Y9DaIyoJDM=@O4pAnjD^AL| zhYKQc;>j>!A1XbOR=pyE6B}m1+>2c&P@V(Hzoz7*4#O~&;OqVF?(=$;+N#4aeJd(B z)lrQ8S_t^{at`u*&2D%1{f1eV}Q5i+{89k=sged_* zV47kg{Tt1+l}9_h6^Dsm;EgaoTC@O=Vp|{?KS` zq!fRoQH4(b#ZRZ(%8b%=aJ`_&MzN)!7P@qG$@JLtP*7DS93PuI4&eIvTL9*do&i`m-wjk* zh1UM?DxusIwfz@Azi&IxmVKY>iSi_hCpz4rcw#>^sOpIxceUITUm^n3cw(UC73U_a z&pMY|bHF)a&no9iYN#{#b zPC4KEcFI|=-)ZOgwWpoU@0@n_vpnNmX~`MqIaSX($Hbj=mOVb}Y@?s$Jgs_`^X%$b z&I7AwIoC7Ea-MomS(k}_c%tHwEX6kJA9$&n_;88Ldii!)?|vCFOM`6L+5tJTUW3la z%Ep|KeTtCDax9O@9(Fk-Tls01Y^nVwnd{M&vVxo#nU~2tS$msFvW@}6Wv1hM$-Wr# zvRk*>$_`&>BpdNaSr^T@?{j#f%&27deFs*y23{fTJ;kxgm{bbj{k!1&KAE{-{=ndLfE8P@H(o@Q)!h5O z@aGgyTubpp>!%b??2ZOiJ+a3#E%(GnhyXR7_%GLL6mwO2uB?mt^_tFTPx0$DQv`GT zabJM$<9=PU|5&eS_>!#Ayg3w&UPn`6*A(SwP*tOE3$D8qI!9)~KAe?mZJtiPdO48dTM2!YeJ;X!F+^snPx@E%h3WMSF_ZXu4ny zaT>k*o~+Tll@uQ}f1_j@t5G{NsH)NSaxK?r9wI=EkLosy=N1PyVc^aTiMeWT)o(v58|> zrrXU8l(wpxFFi7$g3NtfJz0)>YuVJm7*KLwlMy0!3rTd~RNv;}J|b^TodUe~4+z_mhL!To;Vs?*?pzD;*SFs?eE+0^ae z^-nG13gGqBw7Av)yQen?xN+Z_0QWpm4&aM*zkt_UUHjh!c=wYufInV}132ElFTfSg z83DW|CLiQqHGMO{MF-{q{H(Ayz;+L902cCd5mi=mU;n)OLiWUzXo@FVf1r3`cQmN# zi9J4QxhFnC1gP=Eq374LJw8gf(`6j_n+q23V|OI*`EO5v{S=#a=vW}*QWUux2$fkbMG*5K@BE}Q_oa%t}<~u7a0j_m57kHkqM-^LW zzl*>VRL2+BTn;=@b$oySNZ?s9Yoq{gT(Sya&#sLDcAlLJ=6}(^7>wu5@C3NI{aAo& zM|T9cl1^2C+a3K3j-S8b3BWzpW&>=Ul?1Tq3TJ@zE~FDZPqCG@h#~Uz7*$qtJ+bT$ zvL^1L0J@E@7K#eC}8TCn4@p#$HBX3PI!(O$_+!@q1bN0A~ znGdVf$c)-nDbuw|`Amx&OyP4aa12T@J}kyX=(po|-Ic z+kLq#=V6SD3yzT8c^oPWS{5K1tmiE=UK)5=2@^ z?D5YVssm4G*k1~ITGi8TU%3qK`x@Hp2e@tdJ^smCsurj~nZnmYEIY3k#0 zW~mE}%~G$`HcLHdX_h*rrCI9r_GYQIT+LFQODpT5IqN&7y2^}7w!UL@B;!c&`=^TS zN7yWYRj<>dd`)eI`=2SR1F-7;In(Na;~7{lIxLJ=-M@Z~4K}p#zH`oj_$|%Lfa5b; zqQJQ7@o!F!Zbv)*#$);*{(5 zy|Bj%E%X7d7ZqtI98d1p3*b8!TmcsLuwt9&-TkOA{$~w{Rrl{XN*5fj%a-y0tM0#{ zc3a?yvsP3F^R;Q)1mO7&1^{p0wHw5@JYNG~)%lL_QsCLS9U6dZ!uxeK03KF74(!jx zqybO%UoaYs4>GC>;)U~{LY38APkd6D?1}D6D4y83BE=IqG^px{yuOxu;&nuT8cz%~ z&v&YBp6?V^H{Z#)y;PrTQ}cHRyW_Ns(HTC=eqe$ z!FBVUzSYThlGVv~I$9^+X=j~$rx|tfogC`qJC(1K@AT3v-|3cFzSC*5e5dVZ`A+lA z@|}j8pQaqbBJ5tX<3b|Q913pU4W*8e3IKfQD&Qg3?m2(GO@(@fxjH?ROuD(`bGTvPJ_FDLy(6O^Ma$YBZ>- z(KXezT%*=CG*Y9(P+ICWnuPWguhCP2ImBu7i78p5u`4JVZCq2yHddn?8dTLNZ=&TI zy^aV_@BNJCm#CHl7Q(G=gjU zWEgjI;4rT5jv-uR)BtX5EoEIaXPvy0sWPLIt&?+Y45;s4S7$1N_iq=^{Q=&e72cmK zwhzs#fM;4_b8CX*>x2ylc=hnP0B@KZ1@M?vkpSztO$T_z277?}Har04SIw_!OgPB@ zj>9~FWi1+m_nTGY$1Pk9j(_FS6@aY+G5}_G4*s+b!$G z)f&rjL6T;i%%L`?|G=g+V;^!Kr|>uQ=Ode#%;iET

g&BKX3%`-fk-a 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�@9;G9jb!HJ=z?Y#_MRGUD_TsRnn=WNiZbq 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 z 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�k00`2qcFYWNT zb2W$jl>_bXPwnV1w(A4?utdo|Vr-~=uSO5-tMuyVaC@Ph!_$B``<@%W+K>KH&0*M0 zQwMo`))!NU^!-IY7PhU56uo>}h@;(rG8JG9do5kY45g_-ollR9} z@%{U}w;63X?>$Fkah+4mH;cS?L4$POw;Y+1_vv~67!hGa-hYc3#Meuy%HJPVlCR=s z%g=t+f#3ewhxbSt%J=BfkAIl*5C67@E&t2elrPlb41C^yC+yQ?39R{c0(7|49ky@i z1b5Z6fgma`JYM|@SX6r%IOkXc45+qF^Lj(POV_4DWBmi;bmesR!c*NMVTzyr9Lb^m zUC-6V`RgMy?zvjy5DtH5DEDvfT}iwbptTm&pcnDnZJSkZ!fx|%CcZXPn)){>SA);Q zb24`yCt`n#9{UpZ%=YsLyT-oOgx&7SZDM<44{jsu70Uw%J8Fs#Vc!_um9RgpY(?1n zMs+0Y0`^{n-D&Jl!rnc;C1LA)^AYxej={wJ?3>n(gncELoQIfiRb677J|Ak^Vsu7M zW~z1S4|%h5zxUt563uUd;d&}gPcZyl;y84O%;##0(I8zlEnUXc(NjqARpH(i}eQ zWd~Ew)quwvRfJztTch%GQ@!6@TWybm9`X~3*`jp#;dkKV|H+_6Z*fc(}!z|*vk}b#0@b=~Q zU=BI&=9+bN0#9$RW;08o9z~gw-|bY|oUu-j+-|3yA>zBVcL`w+EZ>^2^UpCS>>nDC z<@2uYUD^`wWq0KrOxT5AlHX-_`LK%^pIMxo7xT5bB{3f2bPL}z$*tzh3dFeF)W1(^ zd*Fl&x%}PrRGezKo_f~L;=9CnbcoD)`Tz~m_4N6~oO+sGPXi`pB*=fLr^g=+$5)jtZXF1QbPf7=F*=HCD!daVRj6Xt?{K8^>EtcHO-{RV?IONW62C;dR# z$r+*jUG>y*sy;H~u20o^lv|oNPt?DO@!JSHkNZ}_ru|czYl(Wa({m+Juj(`iBy1mx zMTC8##yrBl9$k;HlaHDZHobpy%MDq67gN{$IuYOGS^0_W<=d8 zwqFU`F{&cr|MsRmVTTVSzsqTHVhG_+A5YYW??ip2$JKTOI`i^9)8AcBi_J7#PZPtk zSf|l)nm)Oi^|US;r0c1}biLF6{CnT4hzKL@_dBhQjf?8PKJHnopt$YR!{dgHy%47h zyc<{7^+ue}l9O@Hj(g)SRah9;Ze)kJfbIq33KxGVRsQF)bn>wzO|?2CwSBTr8lSRV znm%>CWOikd^d!w+I(?y~lxA8}`u@OL>Qc3o)F_{&R4Lp-npmQ!G+g_))>H3*?9|iS zsju+;y4+vh+Y8%DQ(q5#tagsL-`+T6GhwUsEjQEqRfz4K-MfLXCl4U!AzF&HD+&Yk4CqFFeRt^>qs0@2|FAEpNmVg1UD175!2JgC=!u@v&z$OO@ zz`)U_@a5^k(CdIXY-n2&ntio|b81?^uNBN;&=qqyt$PU=qYCZsx;~Abo1J?4{E({ziz> z)bX63*@w9Pi+6V=>{~m36W4z$`mG}Dd3VU~V{97^A-?C4n|gnn z346KMM#84I=j0bg#6yqUYG9WBYJ8V@8FKl%>#25;;d+`lB#U*2qR}BT>*+-_NY~Sw z^KEydc-uc%ys|b(G~t3olLh+F{+{m=A1u^IWZZX&Y8}c=v%C^f$LR4V&-N2_ ziXOjoaUF5pWnPY4pKbm=Ky3fwkt&2uZ}0Q(sl@(#BL%{KQz3+~!*dTKY=^Prca8g- zl_180TCdNtZpQrHK-96?<4uX<3#(e0u;=c6L*Vc0W)OB+A98)7TM4#C-^Y($l#y$h z>LlyCMCBb)9s}PeD&v3hf1+JpZn!>bJ7@8I)(v!M%=(y&2I>0vd9j|4|M~m(CBwhMDownzL|5!vHuT zx(BS8tbrzp_2HuD)nM)u72uFX*088+3Fu#@AUs&&J$SM40?4&C8U#6qfob;+fFn1e z!M5n5AfasxsIxR9w7=_mv)XcfWdH7YDF1W>aeq8^nk8}n-19(v!v5sAionx#uJK57 z;{HCDODDqi-9DYL!yhds>?TJS5q8s)w1pZpH0?BM5%qLHNLlFpPZwBv z+hTbC$3b|Pi-i-b3vh7r1F-&#ZLnz6D%j+l7OtM!0q);c4W_-Q0LMu+prEM>ch0E> ztCcDR7l!4BHa$N8ubOwjmQn(kQh6H~)+P{q|K+M-$gwYJJPC;zRO#pf!8i6ZNOx ztJ#FD?X{P%JI&rr*eTOX5jMTQ4<$XajAu$Xxz10QcF&3W7kc*=VfUMVim-beA?@0$ z&l2O8ex4-kDZV=hJ8Dk@!v5&2A@1K@r$!Uk!M~+=!lsW`ZCeCq@47vQ>^>lEE;d+|5JB#O`@#qkl_4EN6r0ePP zjXCvH|NYaZj0E`)^|bpsQ<$^^!kCAnU=RDgaAomwFv|KK7*O~n&=h_Nx)pv2yb8Yr zZs@;ugG>Co<(d4B^9(s}=I zb57o;=l!HDM(6#B&tId{N?1g-S=l;zY=^PY0c&bU9~_d@_|DD&jpclp9$K+c+v9H< zo3|bq?c|r#xJ|2GQOo1|M71e5v~gjl#3)Or#He;Io>9@g>PBC*^@^&u!zcRw%Qp>W z-`#H)M=#y(6E*75i>QL&q^6k7K3zIf>WSKhZld-}7y zC)z$YIZ^ekQ1g+#zFq^z3>oP=dK(glmHf7)c^7%{hYlUua*37AcTeZIwu;L+CamM6 zCpPJ@kaug+r{SbBVcPZMInI;gFy3m1UXj#J9Vr-K!o+Y7a%(LgFzs9_wpC0R*NEC_3=<}5sYH6hgn^dS)=c*?k2HdctpO9J zy-M-coeATvP_XGt7&t}kG?WPwQ>asafeF*Lpa}WEhTW#NR%SnwkOvfuXTr1(SCax9 z!i0fjijbvj*gOh$hz%=5ozn+Qm^hg_guG#_BLx?!t<_<|#54-lg$?US9l|6gO#6U> zZDztiD0NOxGhtj4DzMFwpN`D`%Z1GJrgFnQd=9#hK->JSYHK~&u;$bu%wWPmI0f6uglUgbJH5n&i3KRwCpN4cm2c&uScGr_wKZ2J3|yfO zVHgu8?xg5l&W7>S){d}YPE>4(Oc?ir+FJf-){$y|Qn0#A7&o5UX*VWJ`;a=)DNL9c zPwjLo6Q-R^?er`YCLWedO z$%Ki+sr!YyOc>XPg5^HUI#Q9o<*CVpfeTb@9horg845O@2@^|D*C893FzrriYbV*T zP894769!zVYb1*!OhR5#=d>vk#yz68)}ILzcT=&=W5YU8Co7Bz)ApodyTOEkiPRH} zpG=t8=@a<`qsmbhAplTYYr}?398Ye|p9#~BrM9+)4fCL2A`=E4Q%|LyGhy0KRBT0# zF^_Z*wbRB-7?((Gtv3@UUZ?8YOg8K!Ro`|qVe&0D@!awX69zU?wf74XrhP$etwIco z5V6$_PTODgu+)tSSwZ}}Dm=r{AtzazkNUMw^ zVfC3XtsS*f4a%<<=ushV&(wH#NY&^L&YaNRakV<6; zWWu;=)TPv5CQMABwzh-`)1INW7R`i-r6|eVXT!WGn2EqTQf?{*tIdRon<-dlCXDMu z9qB|SOzTY@X$TwEgo2%7!bD#xwqz!Zv!S+DQe+VV&Qe=*X2VRVtqo+u?5M2;GGW?F z)Yc9#Vc@U>Sq5)0VO%t|wckvb_8@h#s!1$DL`Q0C?U*odjjFw4m@u&kwbOM>nD#IQ zi(|q-1hvzbOqlj4bqK}cm`7TKI#~`(7`Kjs^<~1eZqy;nX2L)e7294WjH7R$5|}U% zQn7tw!ayhmt9YD6h&GUltrZg{x>K-`Oc=OL!B#V2+#!m$SSC!XqfY%(Hf$NSwL&LY zN6HPSU=7)@7>c(ZOqjTz+M1RL<7QB>9ZVSLPwn&~6DIbcU>}(vL{)D02>O{ zoC(wBqF_UrFc3q*mN8-4PShbBX2QfB6zm}r#(7ga%@@x)Qqi7**)n0^7`4-`OqjMk z1)I!-arCpAElim91{K>GCX5?J?KFi6(>hRFD|L!R2se;|xiDerw>;{1yIxEf7eW1I zEo8%XQ-=`2glU~A*c~Q}qcbGeY37mAkF0AjVW1pENCzfNEKb43F=5&XR2kgBh83ia z^aLAbO6~MD6UGguwpRQMix6!TRaBcWVW28?2%b!s{7R0AT}|#ZfC=N?QBN>-F=3!Bb)=V>FmXHu z`^L~L3U-tU1MjJwK4QYOov5u9xWGD6 zZ3?xudQ6!3go3#}-!G1AeT2BgA^$L@a5frQ~6Q-R&!A3J-AelO+Ynd=^KD9N82?GzQt-WBv zL@#PJV%a zn1tN>psz^EN60PNup6f3^`9uCZ_2>nug?VJR-16c-&|w2!W_qW4;emUz{m+*C;EB)<9Zl5%F{!XPrp01#b04# z#}e}2sT?_Q*gwAB!^e904)pTy8sal}%;<;LSf{Uk$Hw~0NaY0OyUv1ft?X*(2}kD< zUS|=G->oPx7U2_-D@izhk%C=m!o!gtNjQE_gZ(JNUm`b>aQs<1cFRO~%^UhdqzG3& zRL72n2=91<#iZvVg>XdacqWXS(;evr!49Hm$PCBtl@u6@@K?x{B3yZigk5REE8f%- zKoPFIqr!d^;XRQXMY!_iK6cAQ_*&#h5{|#+$Bu>wmu|8MPrRuVC`9QCCXC~}(Hsf{ zD|(ByH7?o)2?4?E*|4Qss_FHDV54p^^`g9?Q(&yqw+p#ar%!nuhh6E@mx%nx(}&;o zVL$5hS>4u0N}WDssswh+bozQANAmRH$rISo(CO3OW)U7zp#&;W=mhOx!nijTl_@a# z^Y|D=L+S;;om95QBHa3po&kz*j6uOv8pPUr|&q1O)SD!@dndrw_q4-(~3q zzvoq8tkZWJxss<3ztqL9^yw>hPrpm*^eOL*u^)B%{y}c!>BG}^uv@0nHy=5Yrw>o) z!H$MbU-&)NdGWJSP9Hi!FPZV-2|)@hb9^=L>-iw#!&8K?qoMdZ-e<k%Z%KL9ic1c%etE498R7uv;d=+aO1h za6B0fI~pR~{}GGuknc){BTCmWVO;PlL^y(7L(!0g<8N0K7>jVT$E*y;AF5zin(*ex zk0M<84hH*Cgik?kWQOC}f!Hk*;W5aOBplBd#EymtfAW|`_~oiAQHCQ*O`ot}oO1zm zOM+kx*f4FW>iS=N1nbU*Sr)BIz^1cdeLIp{3uVJf-zi0G?a>pa`jl^ql-O9wVD*%h z4EO^g>`Es?N90E)1O7e<`%%d-AGwjqfG2liw@k@!204<+fTw$6M?=Yw@|1O!m%jdp zk^!CWQqNd0E?`GxJ>dw}`5B9F{5_QdV-X&RT*-2WKc2#_G~p8RBMHafW??^y@NdYC zBplCw#cr7hZx6Qz)IsgmFhLto4K==8vOj$a06j zB~xH5!oMR|ig4w_G3-hc-tf7e0FrS0T^jbI2p@*rNW$?HVeFQP@IAgws0%Ik_ROCt~1pc5AyV3~} ziTucfz~4(^KPn;KA~%w7JarwrWl9L!*Q|uVli9JOA;P=9W-$q(uA_uNlul;CxJiW& z;RqIuqM=Hj@_nZQV-cQ=TuH+5$DG)eCcNq!Jpm-)_*+rzM-ko^xsin9+5Olp6X6?? zBU$qBe1Gg{i13qdScG2=EtxBQmV!d*8zzh^ULKV^#C-L)tPIEBwkj|d;r);+NjUzH z6}!@euSR|p;mUWi*pDLo5^^I6#|t1}w@ic=O=e{{UJ?O28Y0|2nMJr~Xe7#TMCnMh z8!A3!Nd*O#IleGve0Y%s>}V*y8_f9XM<@zJm*GE|Fs`qX5D4b@j+qe3cgG5hl@NZ& zl}ZTZBV+7JC&UiqM^<~01&!gzQ0fOy9(U2t%e{-$CScE@9t`y`~Bpk0@g55F^o;!_|;dnI@>}ZJanrSS; zQ(CSXA zAD9WD%mq+jtb`bdT*-vMAO2%kIw95~KQbZkyaMb;B}4*pBMHX~#$dNh31RV(l@NFd z8SH3?@TMPG31Kr^`Hex8_GiMl)zQCpr7vEGVCzvdWXZ$xAQTvj@N3AGB3zmDfL&?A z3w_cPKoXAURA4`fa989;5{}o@!ETudpM@OBl80B>!H$Lq-}8w@xL2xb~Hq|?Kf6Jcm^nhBTBn6VH~#uUF9Lz5)=(p@|3wr3XDbg zDdb8Ljwd2vSDNr&$d4o(&vU|l6yXlvSs9L(!@_Qv2p^9eDZ-Tnvaq8e!Z&_r5zb)+ zB1%uPVZJj_h9emFgO%ZUUX}u55$=dwNy70YEbK}XJ`(wngyT70*pDK7Cvqb*9IqIL z-7*pW0y&a|<2A&vqanhJ{$vqeY^IXoh|*R+SqXvHAX8wOIx%ajmbkt0bsUbqcA8Y0~0H!C4JY8Ao}r7f8-ZuLl{Km-f;%_1Dn7gS&@ z!jB?Xig0CeAa_-t^i_4q-Z81qWUdax-Wg>hiawG}IYujN*LxeBm z@}~b;O>*7klxYg#h|ruN2G5mLU@XFG=h8Dk5w1*(#I7{q1CSp@ zxH9h&`%#3iLvAGDc(Fh1mWlAY$dM!*FaL)f4H2F@H;Zt92}hLHWWu&S); z|Ec^G=}*vjHVkYaVH?@7kcQ}P6>aS#8|J5cO^je%9{m|5lL60RRbZ@Sa73MNL@AU^7xtA3ELk zOc=N2s`C4y&x%ndEW+{pU1e)5!gnE8l5jj(7rWAgCn7(Ra6A_n`%#2jO^o8X{bqmqoZ|e}!;F=?*50>sSs60l^-lXvhr5bC(qui*W0Fta67Z zDq~lg@J`5&BplC!#(osxfyj-_aJ=FtcFRQgS>#9&uB-uy9SsrwJ|Bzla8HGBL}}^# zEErd0kfr{61O)4npOxWw-Zq9Yrr<0SNjP3O0lU(KMSFCBzcs zN+twe)B?NG2@#L{$b`UaW?(-mA$}t_ig0BSY3!CMAv8r<34xcD#*T&v_b$p}67*3@ z9-?#+6UMbx2uHBfC>pZl;Wa)K7>jVOnEpUW!tsJ0*p(*S0r^pcE9-?|KZTDExX$Czk2-=iF=uADvc8D|V-Y?I zxl)8Hi-k0czgm4f{!!XF_wl5o5fId;oLc*Ww(49DNNASMhF-l{l@aDd;% zAWCPT-H`F&#myC1=J+Ibe9Cg?*wIizykN#xzn7vw^hlwo1?w=l-L~kmAHiB%uo42V zJ)^)_2@!x?$%McQ&0tqLA&wwFG9mCfHrS6!h*ac85{}n@$8MPtqG1VELf{qQv7;fv zdz4@@c})3@L6mCQu%l1WlLQ1ihN7WLp0e(a0%H-LhFmGal|^>2D@}NR7Te z9IrW~z*vM2Larp?c!448N)x^g`H_U<^^33{Mff%3MiP$yiU4-YM0kl(%nVolt^js4 zM7UEa7U7;|%2ZTD=@_&dDn8}!5-70D@kKJ@!+)s&I~t1bE;ByuWM!%gdOVuDH0v<9 zvh~qSX9R0jnw1cEJtzgnN{F$@l}re{_!D-e6Jjs&BNGCzErtE4gm{MBNW$@-ZoqDt z5~8XVGa-~e=71dy5#H8{#pKeB3gL*-(M%Yp)gZzVY(I*IEO~e>ECt3QJPEmygyV&; zuq#b?Icq%uB;j~nE$l}T?vC6@!tr0Xz;2lcUyU5el867^1$HzOk z>53*UL|U*Mu5w9sxs{^8NpMl*((G=)`)2UlWKjY{7BHI-e!yrlvthDcnrLesjmjAD$tR?u$<4nCm1vQHH7+xYco0x4Gr%zC^x`2TzlPVTwwTB2n!6C!896HV)#}B`dglk zs?or5hVLE33@>y@g~QTUDQ1pTV#@X=rHpCdB!MYo9-j z3k-h@VZPxyyGO%H3_poL-*BDgqk-iNA3T^Do<6n?6%I?Uq?l>#3&VkJ8O#jVzJ!7? z!yiYeZ@4xg)X>oIPQ(RA)nxO7-;~nlH@Prz4a!u$;c}Lz%w4o8$~cmp)4|vttno0@z(p<8OJ| zGg2^C5HBFqF9>ZAsi9#(^c8yAY1rLFkG5rYG`QqTEzK=Ywt~s3k-h< zVS(W?c1y!b4F4AbeZzGSmj;$Iyx$0Bc*h|z9F|^6F*A7%Dje8NBbedZD^xIM_-=#- zhD&2m4Gj%Hj5yzL?K`S*f#KB`=1P6TbuyWTl^DJVfxh87t4ssS8Gh@9%<$UPa*ctd z4^qsuk3xk5dlPE>Ek*mJ3dRf{G%|O1H)yUn+BFM{KQCRcvL61t+2Fa6e|cF2PasmzEueH_33~(4J@bcM~ENnw>=%& zo?ioHgj_>UW6YBE3x7xP?9Ss9xBun%u6-1DV@BsL_+kpTb>f1I33MXHQ9K%r>;Z1K zQoQ)$L7LtDisIRp&iv7(G*lHaZ&EyY@*u@+|1oT-Y5f|CyDKQ3t*XkuJC|moB4#bc zM`I?BCMDh4J**JXME}?j~Qb0b`<{i0Lz)E!9|As*l@g6i)`q9fyy*8z`Q>Ar*;9 zerCKJ&LDu1V?iY5i@!Mb0+FslN%Y})^hwBp55I}@l95(J8r5;$wRevxwr!`I6no?YAi&cgc0t z$K4YYPrfG`2PO}Sn4=Ug4#z(x0^EN3bIh6OCTtu5?yjP^X_TenyC)HIGsP3#XMEiL zgyT}c0q$O*c-8?UO z6BR{FM)72v?2$fh&%Kl_HCoDXHQoOhUw-5nte?W0FkY{)MDIULF zmA6cn4@gAJNs6aE+bM2GUB;Zr>JH`&bA#+|A;pt-`{vo@;|dY;Es7U<)l=L)Lh<4P zXb-Zx!xWD;LX3QPAY%GWp-Y{Q>;Z14Q#|e8hE~Fu2Z`*ih2mz>1o)0gjw0rMiWi?g z0N;JwzC`ili{oi__ddnrzaYE35H4cIPG!!Re(kxK0JmSEczWY;in~^d7fwmd;ALqM z^Ekzmi%{PEUZ!}~x-a)Vz-_OXE_EjkQ-He(6gL%e@?nCci1{kT)8$eGK5p-%c>JCmRUdaL z$8Yb>+&tTspB@2jtG~dUiBgWcITSZf0hbr=M9g}Mr;lBY4#kM3brHPoz%h^)1=OjDcVFPY2rg$Po2DrP9;>F(}ySxx3V(y`M;TewGrzxKN zST+vKm_&B>ABty3u>;G?LLz49bmmO*XbVaVgD%CHdWuKapxy)AZKAm8Cub8TT8fyx z6i>RJ2sIg_@7;))Hz*$Wk?X3T-F;#PTdKKQZXqz~Qp8N5c+>#x0d7}td?L1`0C(S~ zcwr^P$O{f4=6Q;z8*zgY;PzdL7i#4&VZJ7^yOCEgXRXMEiDtz%0~w{qNFPVsCPw97+d5wn`&$+^%T z;5MOnbT-b_0C(ntKig+k=pQQ@o0d1P$?7Uh4`WRCgXA-&uWM;(zF}>{nZ}sz-$u2y z<8Gb#f1p?QUwXeChTooNj5)Jz*^1`5O)HyEKLqba7uVK~8@sk?`Rth$=3~Z~Dq~FL z>{Zt`t!P}fvU#>hnO%6jsq!pi%*`L*&Z%!++T7ATu#&SM^5^6eyUuxe|0~x$y!zDU mK__cAo(}uRfDak{5&XR4TEF(!uGcmk`{&tzTX)B(-v0v&RVQ)) diff --git a/interface/resources/avatar/animations/jump_standing_land_settle.fbx b/interface/resources/avatar/animations/jump_standing_land_settle.fbx new file mode 100644 index 0000000000000000000000000000000000000000..1a11781e22aa9054beff289159725f6aae8862b4 GIT binary patch literal 1531152 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%0DVtf>fb~zxA($Qdl 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

uVSd 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%0Ay|d(B?v=Ttnh#8 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 z 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 literal 0 HcmV?d00001 diff --git a/interface/resources/avatar/animations/jump_standing_launch.fbx b/interface/resources/avatar/animations/jump_standing_launch.fbx new file mode 100644 index 0000000000000000000000000000000000000000..06479c8885aed86f62e2ec20437f0b7c5f3ce13c GIT binary patch literal 837904 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 literal 0 HcmV?d00001 diff --git a/interface/resources/avatar/animations/jump_takeoff.fbx b/interface/resources/avatar/animations/jump_takeoff.fbx index 4119b2417f72852c4c7860dcd9842e5ceb007c42..39767256764faf9cb1686d6aa92e7796d62cc2cc 100644 GIT binary patch literal 685776 zcmcGX2V4_L`^N_hii%=6dx_=j3ieJGSy2=f#a?LvqmW<-D(Y$Utgnr;ooB_acNVOt zo|;(Cc8YrThP`X--MpX8PIS4rCmgFbc7*771Xka zs-;#JVMtb~P)RhdG(vv4(YK>eP|F@|G!fAnL#ts%jV@8E*Y!aNc_4&xB7}UteY=~+ zz$)T-Xo9(3$8b&KqhO#x6Jh_Z zHeM5EjEGM-C5X=DX!b#NgzgHyk)x+3!Vr8b7eb!}XLGjK>x=_}y%0hLJ-%m0&jXuc`oF5^i7M%5Luhk_PHNj00LfwVu!!%KPU373>gpg5iK5u(%T%0x$ ze>1xyD}3z6KUoDKl*^u|-Vjy+A;dWn#5>CG&f|y_;a_{7$dm0`awUPB=|LTLo{}HHZZ{}>kXN7u;*|8AFi8#B%?lBlQ?J{Zm&7tUU8tk4iWJhpfzs%?IV&SKH!$rd`qQ( zmhkm}(in$Nmz;c>?fJ$yXdJ?fWFw3k?po8ob^9*%TpT9^DHcNr`PKLJYvNniuTEoC z-8xMhG;Ug_PVGjG8tueQV`B>nn-0>(X(*|RubwA4d1HU%$Io5QLLw54VG%<#(SWlp zJo%IZzw7rcM3%LaaDy%Q21^LXAZ(D5u*2K)xG9Ejsx;J;ICJaf;xp~Qw^lS$YYsDI zy8A0`8@pRx=&pc|fGDGOh$hsaw_n_Zmy7S1aN}~mR>VgnM|kDt6W}hn9-(1nflfL^ zaGh{91@u6!C$5Lgm!tSdZd4+U9=Z8xgX6`M>o_>NvkyY3+Lr3K_g1wW-?VR6wRM$W zznF%9jx#b}rumx#heM{8Uz1vX^;LE1^WZdX)Tqe?9Mn)a7uFFq7pfwYv~kfb>iX4b zSjW$=QFHEUijVyKWEiF~8nwFE#JpbLXZ>$e8@G1w6~ttk3VM6-W>n+N@Z>J{2?4{j ziS{eMR%f(}AFMNKVm17H70j((=Hjqgd|00EVcJ+7Jv1GM*5pGuxPuIOosr%tw-(5s zhaamSAIZ(`-y^f^w+)UK^c$$x8=~p`ayn0N?)Q6Smi->W(VW*Fq4ufJaWNL7bnd)- z(hd0VLIPTFc$OpRfSYK{H&K8yOQ$u4MMcDEf+C{0MH%ONv_2^^PGkSFLsEPswwvWE z&8l9ATftW`uGGKfA-%Pic@g3+9Bue9<>MyR_(-irXAIQG=?(ZQAE!5TZrw7BTdDD< zxxwHOk-iAX$BPxfx5`xrtBHw7iZcdA#A^%@z?Gy3LMYUrk4}ox7*wGeLt=u)euXpQ z=I}hk&HUWd*ztNjjtbY8YLBzjxr)f4Ln$9AaJZzvct8A;eb*SHt$Zl_r9gGhK>r=g%YoS2|(( zBtw*@BYzXYm6!he{e->Qngw_Xn(-18<}k9CZh%f3A7+e*8bn#2*y}lBkVfU_$6cJh zAKeS^X>!-*+@1A$V+Vb-=3BwQ#~eXwc{*!iGzN_>N|Tr=U^Q3b_{hs@VzfFfcl(=o z829OPS9VSC4XpWZIT5Pi!;g_mIS;Rp{Z5aY=rT`=W${mPEelM`bQCNEx5i0nzb&xq z8Aom{2X25XLLYpumE1)WpAg3Zz4a5*F*S!3vo?fg&8?86OY>9W0%t=znVk4!F~F2tKvotK*fySqjk zJHYtg$v2FvMq7XwXI`88!KT;D1n1yWB=VMI6sv zi=3}e+*&Lsa#)9?xVWO+ts6cvmF*k(UsLlYj$$0LVRRW_7ToUP=%e6 zB8(b?j@xh688wCky?r9#MEXyHTzi4VcxT%27Y6$!7=zF;CMHp1w9ob3G~8Oh9&5kK z@c&`2M9PAC0dBZ0-!NBej)p_EL-exSedXLPhn-dz>)LqR7UzZFRPhMq*HC=BE)91= zalYPa^UZRX|1O3IT_S&d;a6PHb@B!tlE525Y{*KNN}_#a3r4kg+O&QL~9K8 zED41Bl;X4GwvRkQ?c0$K5W^B8qBKEzLx?tBYwW0tONNx{iQB+83*1EVtqr3#CPt@8 zOzdI5I8bla5Lzapp`KzIdMu)$USb-mR+^UwFMqk&jN8`<(de>{uEdNk&69*TBe+#} zs6q2h8}2?y#dtm<#OnBTq#Q}J>N zboo9~u)rqMqCo4+v?#E=-oR0m>Z(y5%qs#et_WHbI6_N#-k46j+uZGLYmGi$V>D=^ z1Sqf!wx-;>SR1_!QIl(6Md~<2&8rg$ZA1){mdkN^8=`V4P{}zL!8kJ>Sh|1_rmd%Jts>YAJFv6sGVI(DG$g&wxN$t$C8Bs}n z#mzM0o#K`_p$7YQa&&+$HclKuft7h>phiR`G%1TlM5VL0GQY8pry4FDZnq-9=-4N= zuTlTIwf`1J;VGCa*RBctGL#zkV--Gc!6sqY0R2$XO#!zzG6?@T{`iJ_@T7w#*8bUh zsKyY*Jy;i`PDf`E{YY)kzx(m1(|5`EQ7Qwq0T7ZMex5>8g6b6jYqy;wxpG&zLZ7JQ`1 zwf$|T;=5FnxT4D<7LC!P24K2n>JA!sg2Vb zlmGjlgcjG~_*VRwxc$QK@hZH$jL=1CXy3B8%l(g(ExK*h`7Ju`(`Vrp9d|GL?Q@#I zB*PF5x8GJA|FmGgZodaYYw&5VN}YE?IneNDHQyRqz(I(QOdEI8tMh1=;g#Tkf}T(k zd4$yDGvqe2g&A_6a|P<-;(YoKxfmp~kInOETvaxe^bG9L8!B z6XGJ0?VnZD6?`n0DZ|+{`1(_5oBu!!Nmr-W_{Rl+)2|3W)|7Zf5P8hUf|5RN%v^ZW z@J|Ygu8H8mQo>P$`>=yQa`B&JCXTGdf1=EN8seR4cRwWUOw+dZkCizWkw>O)+An+D z9)2jdsg93Kb_UjR(jVG6cf@}?^tJfXyzF0Jz1b}K$IB~hd{pM-=@4*vL^JN&qZSH2%?Z9XAxi7rTp8$;M2 zO`OK4*M0wCgwP>MQjEx?c1Y~Ai7zN*Xfu(0*7TK@=Xy$?{v!KKmDp!_KQK>ghh}ia z3k#-*pR_#ZzDLSmoo>w$Tug^28vsV6PZeQ=-Fb|U-SDzVQ7^}#%? zVzsSWUs|4PDSfsPndd@@eU@ne=9v~OvQM7|((?QT?$b|fp5r9;nX@67r=Qqs{CkOg zCc}Luv=^yuTtjKvK85?VwiMZChQvN28iCp-go^C5OCxD{o`d^L3l!Ps5s7^UHwN=e z3liC9^TyKh+ynRNC-&NxCb7>tO~5=&pPGwX4^?U+Ezgy3pUh{Gea@5EXNjh8p6^BW znXjp|Jg32ZGB%NYnk4q=(G1KJp%&u&d@ZrhBuby}MCLi5nKW%5!hKrA=6O|OpM9Hy z+M2$K%rmsPv^-D4eKM~^_IXfZpRHPed0JkJ?6YwTX?gC1`!sootlM=G`>f>;=83+D z%v0qrEzhNJpO%jz`yTAqpMx1t zTZ`Blie{u~dl&ALc`H)eixT_n835+Vd=S}ZNPx6F|AG6o{^>7nF0)ANGoU4yr{5-# zeb#R&EzfOmp9yIq`&=Wj&uW2So@v`e_E|bmTAqvGKK-_e>@!7Tp9NVkPpeozbFk9# z91r*Dw?|~2!zA|k0q!$xhsZvkNbEDd6|AjTKf_x|)AlCZXWC|wdHyT0&#pmWo(bDU z_Sq&#TAoMYKK*uy>~puoK3lW~^R$ZX)33F(JU798`iZ^9uaMa1k8Qv_6Sj!dws;$9 zdHzP}bEn8Yr%LS8I~dH!(?ufcsHvG)$?68r4b4$L$BU$wY37~4)-o`>K*Gp>m2bBDw}n}mRQ zW}Fe(XU!04d9H{1R9zI=XR5?L%eM#fREf>ANPB5{&Vl<(y(%)#NfP_?>Hy{$epzIn zpC$JB6WpijoX9>CI!M#@1>9%&1(AK;k=UoEBdBfaS&@DA=qN4EOK_jz*F^StLSmoo zL%}>Vu8ZuG36+*-@y_4-%xV8^&=5t^DZ6flp|G>8=W0v8* zxJQD%zm^9fbcTC!9v_*WaCsfdKj9+jmwdS8K=n?1py1aUviNlmE^2fq{vj{IuWg9? z4GZG)ka#Hg$x<25ggT`8c0B0Bo5sB|C0E#hh-j@YHn3;j&ivT|_E#$<#c{tzYJZ9m zf88-A=35KgQMe0lB_}SnGGQCG(nt9A0*8;nXH0asGbbtS{J|x1M{h4qKn9#@2I>(zekie4|(B zdNl6G$@Syiu;tvlz=ZEu+}=f|>rZf?G}i;Vy215{UHKebv+)idT1WmFS&mZC&s=k$ z2h_0t(iT(o>~7X(vz2SQp)142UPvGGxbO#cvu=FeT-o7Y_|EidYtN|gU?JT#ZeKVf!3a|JW&(_++GpDC3X)>OrRNMg&&>ZUziD1XoKIW6;_)MnUA zS8eKiag{A>gEW-UuuLJ#2;8jf^54@_(elseNh<&By(E@@U%vdg(!%AR)&`e9w~b;i z|2m{eKMMEcT>spgqVbXG^1rQ@-1^6X66?RWJLKxJTzD8 zKfLVM?G?MI*-0Ctcivr7o?($GW8@Dv`>31tccK0#^@$9+=KD&`PXFXtG~q!m3)>)_ zDObPq1M>*nto-`#uWbGIC)R(swEE8<<-GV$7cBleXrcy@sy_nv<5c}e1aB73boJj7 zF0=X{;y`KD?;qiY>K_-OMD^dqLvyA2QP)jZSj^x;bnXo7L7}O?D?x%-8j;P z>TfXkRr_A~d>Gbi}+Q`C^=^ zKfRZr`nf-WL8|`#xF4tLKdb?+{hOj>R{wn*D6RUNN4uf=$3`nr{WtK?T&aH5hfAZT zv@x?8FV3WmtXq*`nJE!x_x<@o-B9B~^-o-GGdEe^*uqZuA(!RvfH!7#(`c`Zc?XL! zLvgdRtAD3P(dxgdAyvN(pB203_vZk<`nlgn#A|;apSs_F53w`%`ps6!#Jk^!7=8p! z1PmSk5U?diCIJs|pfm#fW8FZ&xL73!xQU160s$Tfsm9IBZ?W$JHPx43>}U4;Q-P^4 zfX`cYsYVY_v{WY!AeHLx_^jAcjTpq2D)$mA$8G8*e4)0#J3P^qN`0hQWU zE3;B(;XrAX`atW3O07LmiAtR^kRO^0mC9*6dU<~C_7r7=aFxoPDRi;|a{@OmyHfKH zQnXU*3?fx(7kpN1r54cfmCF4dHm+35EnKOExZQM3M06K@LjP7e;>uzt?#}7DdNdxW z*1T~tt2F=zN~_knac-#At9U4`ZK^kkSEO1Ida&DGq>awk;j0xP>(1f0aoN?nJ6_Rh zy%A5U)@(Zdtk`NDG?=ee?yUm2TGJonYUMt`<*ut?1N2F8(HaA3Av^&0=Txpg4hG8g zf{r&y&U+=la(|y-bT{Vv7miMR^fDm`!hzBtSfF^E?vrg1y*oSX@KW>g%sAfIi+0+lNRbtNL zW@WQge6XTyH5*J~s~LrO39HIRN5%hVZ?T|3CIGE* zpfms$8r%TDEj$$008l5o3;;4!$hU87XEi%}$ce^lT2$a>fmhx8F4LIj;>KkGka4eg z`6|u)8MfT>AB|r;i&|KwaI-Tb{2Ar~ZdNt`C5(y!(A-D@pg%q<7J$J+ot8owuLVmX zZgL6I8#Dj}2XS{!5Y!k7Ku|PECIlfkP#OeFliUEoeLNJ`AYg~M41wv%n0bHBKc!|r zFEN(c64{(#QFz0AW!wCsUVs~y1;Mcke{5cNvw?-Z{djTgPnJRq+iKgv$YX7KGFNf4 zvLPrtR8a^5hLRwN#%IMskT{%&K(NVzatStBI0)KAkZ%SKwy=f}T|?8E`_k%RNNM<)(im;er{j*`hi zKO88HgDs=nz`+MR6xTTDHrizlEK|eoCB^<@W>al7+oTl9%gqN<^S*4*+`Jw)E{lWG z8*`Xeyi+l3VoW`z?fBvhTls#j9_hYKEYEPWvN`ZGDat{ZiNwJWd{!(6Q+{^hz}g?; zpdRV=_&V;}4wS~hUt`?BfyY=r2iG|0H`ZkiR#Yhw{66HWnw_U< zIiYZJPL6|dOAL)0sJG$9WpQxfTp^}X>6#XH&f0>e>V0!F?7Tu-mhG@KW8UIsWpmK@ zXGJ;a{WFP!QTVJ_4w_GJ;vlsy#6f)$2lsG~P8_@)4{*?UoJq-uY0{+`viaoGj?5a+1Sqw@JCkP6lppA}oM^CvqM zY+5ry!P?(yPh80VihFb_*e;WSg7uup+a%}Xg59~`nqkoZkMJ8!kE##i#$`oXlKbenIE%kx>`@>rBjHmfs;veO~Yr!()E6-6I}_# zAi9XR2XAnXPIPUa3eXk(Klya+^11A#Z@XE|ZgPC#IJ4+~GU+;t1EtYbbqb$^qIBt| zC_&e8JTzCHp9rlP6W4F1naw!)IQ_#6PwqMAK3*5T#F;Bh<@1(Bm*sf7h3o5eVA!!S zzwY1KITyqFH2HT%|NBKOQMg&zbgi7KC|yUUlIVJj&x)lBr8v=rv=Cjyn~tz){5YKG z+BE~9YvnYV99+SH(m3#&?gkEqOjm+~vv_E(a4_;_z}b`yW)_`4l>BZ%Hikv1!*eby z9&WBa!vzj}5DI_UJ%C{=Al$5M4%W|5l!NpcBo1ETvtl{e zG}DO#zgNxpSEC3wq3mlo;!Q{I6o7+4GXW0Pr^w{sHV%}=LE~TCz`>|rl;GeB9-1p0 zAe0(C&!dI??&D!^5Bp6=`04WTElSVi^Ojw({bnj!uw!PD3U&oPE4E;F&EX5S&i79b zLUZB^H}^-D9G@Pv*G5Ojk$+Rsdlpc!#yLR6_MauQV&~vMX%+iumK!S8Z?+N@J8d>U zG*>G2kl|Ra84t|t#is{u*J)FhVNsm7q0c}2%y)3(vQ{wJ5z5fz4Q1G+*-+}DQJxm| z`kECRjXgpvKhALxgxEQXg7CjNBoNl)vtmIwFwY5ujBX$Z#2bX7a{&;3ng@U|V6IFM z7UMu^AiSFE1`wM3ssspge{~%M)0TasSEhhZybWScyHa8XO`c`kyGFi%ksX3ZmkupOTj3&M#7P9UVW2SFgN z<;(pBfG}YJ0K(wkWP-372TB9s^KWhdq2+ufKv**0br9m0O`JackeUq-$+2SZ%gy9Qif{=y-rGb!hksCm0w@3*P*5IMJvNS@7 z8P`~~hg;02w#jRs5s)SLukbw&apSTV^EDPLTCp7#lPY#FJ}b6j$1mk8*7y5jp84F2 zzx(7~2jp1Hch>4+i60nA)E*FO2}k?Qh= z+j4Y{;YoofYSu5ubK|Z>Wf&IK+}>kFyM5-3xN%t*?yol6jlt8x7`AOTWa_cLfQ3Cc zbm6UIRoh#vxLMg4)Lp7523?nuFc^l)pL22JTk;RKy-r;6tW6)%Uq8Rj9LBe1(J}VZ3S*x8e zNT~*3KwQS(!yP(d(0(<5LF1J&G0@>aX&4+>=>`nERw;o&%qrJ0@bVgbqvR$v8$L^W zwMSoWOCFi3H;nCL-h&&Lg~4;1ZSm2?t8U;Mf{BVBoV>2@K-b zx{d)t%)+rB?2iGd7Ixw8W)V`|$=kQZ2Hd#pdbQ#l6?#yi@b9F0ZHUi`t=D$z`Fa&R z&+j)5*Q@X&q)@GHP%?29zZm!ERIoYM0|jgSU1q^n{(}#cRV~?|IGR>413HQsmx=anAzS3 zH*GiUZg1I+o0ZMM`*pmF3UN?sJ&6NDZs6c39*S!mRNm+^2WUs9;7uJ@s##`I-_+KZx%G=_`2AuFHRhjiXgaFbUb z)GV?bys-45#ylQ3E{lWDHrwbwc6DOdC!cKn)wc^UZ0D4)*+;{RS`Oo8Wpj{wi=rIV z*h1o<13oL3gM8baI0#URQd-S<2+`IQL<_ox4*?g7QsVHB~car$( zkI#zb>%?v+zAP-v7x5P1DDKmVuL-*Wz8de6&sRLi*Wg_;`C5$wrSbI{C!y#w{Vo6E zb8wBXC4VWv7ZUPS*S=$9=j$zQTozxs7W|$NxyzGbzjU}csJN;=!wv}Q)VxXR33a30 z{Fr6)mAqR~z83B#@nyzm#qxF9%=0C9)ndkd%oq2nMeft&0E2z*BK`Jcr9HsZHN^~| zHDr%W2-e|1X%Kkq?BQQ7y<640vV|=$-^Xxy$5eH5vx^XnGAjzfQZosHgZQji2x=eTArL-NF%3h& zeU@y0i8JjLjx{U*1`qbz4YD7Z-sC^u!V4*91^3@qIPz~W=8m%#nQ(dS;{&C^)o-60 z;97x);@S-3v7aBB3vhM&Y8&0|VLl66{IhNJsgB%VN1C6_w086}a}V6OEVu$Z5PGq; zD#Jc5e7f9<9rw-bk!!ZmgSO{pe#6bmo?))+R}`+V`$=$>Kfs?A3zy$v9xlPlyV6cz zxVSd#Z~?Ec`x*D;v~qiNh-ZpBGI4e8fJ_4N9+X2s_(3-iunG^wH3G69a+v^LW1kl6 zJ)7;u9)JEG1|d{+PcPiKECTX&=(IMeXe)+2{^aCQRg1Hsq@dv6 zawv%T+YJ<~!$Wb60;$Gr-q(zXq@KSX+Zd?`xVKLPv zjCj_7VYlf^%^A42f`#qTci*LXcS9{pakH{1xP3%X3OtXJD5!?dilv~*37!JMU&l>7 zfGO~CPyoHfaVqZ234vF~0R*lem5D%+V{#DC9&-Z%8}U$FLm=OA*Ad{hbx+@H!8TWY zQBUFCyJ%NE=yr=J+_)?RIuCE~&bLZK3metuV&OJh%3Ih&)qLA_$W@(Lft!_$z`f&& zBH(p`gg{MvRxAQ7Pw@x{eh)MKI!1u|Jxu#Vz##xX_Av){=>)>(lK=?!PsjwJ%s+BK zF#O{N5O(09xCX)xCtU`?^65dj*1u-Auo?GN;X{15$3F739-IG<2clMSC!`__i@z2cV4J_+%v$8>Weo|2o3Y{W>&;Xwm3qrdyP9Rv$fglh! zbr<6WD>T4QEa)mw*;``7;5 zDnfBT74}cUjmrYTSn%EGg#D;fzcWe9y`OVcc0afN%^C#WfJB z{OdXhJtEPjkt@wCQ)YlA`5E`%2Y0-+wHSpPmj%MRGSAej?=lSQJ-C=9PW{l#X8V}p zH~(-B#*CYl4T8rxMM0=^js!w$d{!(7o)?`!Kt3P{#3w(}aF?p36V^kx~9l+ZKay z#eTqN#a3+oD}2QY9^p<&_y7JDpl^$L@E0*7F7o4WD%c~Jfr8y~QD(tD#DUTZ*8h?l z3U=HjJ_pwd_9h;h3;X+~yDOK}|M7{LowuVLy0n1%Ma&n4M>V`+F*m-<=Pm2X{lfd5 zZP0>XhOHfIyOBDv0KDT4z6D&ao}- z+}y7+Wa5Chl-J@Ooj6Fp25|7#6`35oz=6^@2)gP94yImJf`f;6XfAMo!pG#S-g26m z4Sy77Y7o!A4GZlxsQj60E^wfp^htfYW*Ecve2Bt39L;B8pU<@V)b}gIjKR&y=HS3J zMLD>4jl_Z1b!i-wz3Ie(ssh9TaV0+(_vpmI#SDOh1J`A8@Bs%(GiK>b4UHsh6O25pf}(jC*wAVDfE%gX1@4a^P`` z50u71w_9%DU?CogYwMy9cxbM0fRLri5^wuLUS;UV|1Ku_y++#>O>gsg%P!cFw-qhe zCAUchyC0twyMVcLk1trkBiw#9@P(Uug!|h9hVpvEns@k-IF;x8gu) zCF^z94JF(0E}w&ICA$s}&4rRRT~{BN_~gEtJ+krenqDKg*CT4$sPmNHXU=}lg-drH zgjCkctr>RMS6jJ}QwuX}nb&d07FBFwVR5svNtkd?Q4-ePBav_dpA}2O?T1bzF!f;) zh>Q7#_W=?XJp@RYbYCV3dvTyN5(+By4#| zBH=tfE0%<(Pn<}wJjRO{!kj={&NGhy5>`I}NSOIZCJ9GypfnQ7Jaz*KQIC}%!Gee8 z3JHA*GpaiW&Fn?r1{vNn@G^!$$iLVV7f7g6T@R&LR-Ld0&zj#_9;L@ujc>>3!lm);S3IxMnaWm zZXhB4nGz%%!$Wh01cXdC620uNJGb;M$j=F? zwq)1770Pd6cOLIjzDAcqOqn+>g3$ksq9BZYLjqwXJ}VZ4zur56kai0% z=bdK+;%YwsTL6Tl_W%gtZ)Jio7Y9lM;qhBHfKcb15+F=}=Q;>?ep^!F(MB~Jy0;EW zn~yi=EqymEXGv!hrXRf-vPh z34{&!tXL4@KRJPr5&_N##KnBE4*&>NJ^>(TKga}O2@aG7!s`!i0HNteB|!M~qw63b zgktkPw7+0Q^|T-VX>F?C)YujmapSTV^CdqiTCpuYkt#MEpA}oNL%upyZ0bN##daBx z6dy@^zsgbErPE^G?<-KTr9R87*iJZ5TE(vV?1qYcf`{VT=6vuMmn&8kW$mA{1!7p$ zg$K49(>|)%@Ugi}p`Tu;Q*q<6F5MRo?K9t;R)S&2UHepSazIfFJGwy8^r;;>SZ?BG zWrI-htD+zTeIvh*D997*>73Fg|0!hzC2*pZE|Hbq}s@)ZxoH4u7dcNqjU zuA$}WuUE}1ih8InY{VZ@g(SmttmH>RZ@{tqWuXJgQ+~8*d$IuAfxH z@(MRA8-xZq6a}G24iX3>@L91SG|lA%LdF+xMj$Tc@8B+-KzQv5fY30fOc3I5pfnKn z<#YoGxjgwCTmvE6({&IK%4p?V$i6clo^S!#XM~IgzCZ6-i5r()vG;L~3SGMM_?{8CEAZexN%ui!n;eRSzpo)s@b3O*Sq|8`b#tG`}9ToW~L#GXC8jcvH@$8hnG$v zzy{?Z0X7|<6${vBZzsU4o)o}{w+SC`r%r%v_XYqPkXJrne>(u1_+P-5=9LN91so_1 zu$uY!BoqbAkWUG~PT`@s@R1r16LJ8?zc0~#RQBfcmIc_GzqJpJt^Zfe23A@0&*k)N z7WVRSOJ1#M2osB&l?~WhZ$$w+;Y|YUIX){Euxtf+zy$B|@%bGCR@gCvQC^tXH9tQJ zC$@I`0Bo(!FO!06I8Yh|bqlzGf?)-epx_)Hn#&aAc79>vo|--`P*DABHjt6OWsfO~FPVMJYJrL!#gfJ}Z`jUPX8c1n=@mACD>E-sQu+ zHMDC&h$fcw&d?qO0R)N^0TB4TpiBfZaG*2<8WeH^0wW43fxtyPG#3!)H?-Hhp9gb~ zNSA2v;pZbIEUanIuXl47{9yJi>;eMbJDwC>@Jn-sUAn8%syDt@)$H>h0uQfm7{iRi z&Ek1AFIOK?ajLMWh&Zh-*6F{wIVp_WAquF$o`~c&TC8do^~YbF; z`N0iToyJ3P?M}XSQGRGHP=(N`jm1v2Ri4XT_qmTjhk7YKt>k{afjx zNod93?wn?=Au0f^9c5)g@C*k^gCMY+8z7imP6-I^;i0((0e3&a|Glc+p8PAWO%EuB2Wwv;KFu%Z!%VJ>X2mgw9=Y%qBp&KnfP4TPEu?D^$rWktbyQkeu+fhzo2v0#<0&VwbmfloCC z@o&ZB+OWS&1K7eEjQet03SF!QV0EC1OsqcOKxtTYsG6w`@^Cwq{4Qquh+$#55klQG zQAWL?9vkNQ?LX`rn%_1DoWGb|RSB$K;GwxRwJ?KT?LX(wR!!gbIBpqttBsJZ)blI; zZL0Bk%fjj}ACK9;mhNX^GnRW?uVL_I*l`uT^9--)X_<_hl}*6$YKju@tQv`cg4LxF zFtip=fZ(%{jCq)VZ-3_i+QTy9&YTdaQwu=gc6HtxIeS?3KGv+>Vi#!-t8@*SV0FfU z(!g3>!wq0P#Y1sz536lWerT?MwRhC|9`{nr?5ugm_x-OY2bT56s~bF1)Jt*WvcOt1 zYVqg>7mG72+WaXtBejl&y`g(rpyIjGmRq=4*txD<`0>O|tYNifvb6yRN@FX#uN&A3_T_VM zjjdI9Xs)n@(6VYV|L$dPJ(%r@H?d5cRvb9w{{=TLi><`7!D0Q{Rbtp8Rcf!UHT;5_ z-H>;2I77oU++6`6lnw#Flj_fh}kkt7aX36i#e4uLrO- zs*X$ww&Fl(6nNEj0|g!HDnY?IJT%uR;2tI3&8^s&q`fM~*12i-Q{1@ha`mmJXt{Q- zM=IAOd{%6^{;wflu7Y=OTPEOg{r1jb>NeIj+@n*$vJHWP^{p?nU^O^UTEXtB?}ma! z4U{O@z76=HxmK`wXC6E4k8g+U+gMYk1>HaCzZEww>#}W%EB@}-{>}dE3Y)E5+`UQ+ z+cDSm{dG2``M<%<%I2U^Lq$30)sV!&Px!1@4n8;HIjD>f${(Q9#@l}(Da;rVH7LaL zxK@XO*$}d?jk-h((y09W>L3s9r|dsqzb}2>2&nc7jrepq!aPFlx4I$vsED{QV}!vN z#!=I*i#DGBtta~z+yy9P&8P#txi9+TXl|F;BQ(s5`yL;yPXL44B%eOUjbW6hnPS6Cie6!zv z(%$rk#(I3n&$xu^ zuOjz{f%H*>f^{)*Nt}t@HQLw##zayE2busGY;TeYKklU+(IZK%+J6tP<+tC%v**EG zODM;brgRgm*Kj7HOc>P^NMUeOtX zHwRL9i&IdNgv)s7pb4L3nD7sjfu*_oOqkPxZbIs9DJD#60hlnNh4Liy_otJP@(mbTxtgQ+HO!zHG zc@utWO(!AkvWz()p*4^}RBQK<(6|lV1XDICCe&yHq)@hv@+M>prkkM3A!AN>17+|4 zXW$MJ_TWsQZ41BLQcOs*zbJ=4GOaC^2P<#F#I|%3QtQYtVR&1hjN;q6kA#-(=pP~L>19qA@m3(7FTt0R!XXPkjMNH~o% zfk?>kmSVy|D1|>eDsRGqP`U}GhB8c;9txN+Ce(c-bn8SX0r^QWA-EHeLi0|_o1p4U zHzC7uC6#i=T(~okfoEs;nQ#SX0+EoGUy2DQp%nJv6qMY`UKvI=A)&4e66V=Ig(0l( zri8iAgzzqO5>ksvF(IrAP)9*slqaEjSGoyE&g!U4S0DqQuI@A8F3toZ!AH`Za1l!3 zI8H%H5;k_Do1l_2F)!-|m@ucC`%D^>huOOsMOniCVaq|KqRC~TB1IIQn-OrP?CfLeds1+l$2q@ z_CA0KYx}s*gi(FzB&ZroAz^S|Acg3@%9GHhAKirXqB2Zq)(^;_c0c!-ki9?MgoGcZ znD7=#;UP{zNfQ3SLx(=pNhvJD1WSLwgf0EuXTqd#x(TKNQcM^T4y2$9SDu8<5p)uK zs>m>*RRoYh;|TYe;2lXfA*HDl6Hp|O!YiDDk|bQfLx)JPIAcZeD1tm$i ziH8o6kfM@d!oN@ke{0-l!onE32~0jICd`NdOc)!ZJP9$eS&&dfh6z1mfeb=o-Dg7i z0dx~G9J8CKr?QI-08+>`KzS1$ph#ClF&~2dmNT@N0ZbG`GZHuylfD{T2Qr?6&c<2xb3B_fY@Bqr- z3eLbCB&5aBP4IEt`-{39Esq0Cm>Z|O3B%**B!v3NFd;r3$RIr4eIzu{(M?DzCFOEd zRR^R{N~gRDHav8QgwQfFOn3=pa2IFb4ia|h=_aVkN-<%*9xx$Que=H466hpY9YdFL zvoZGZ8g0H#Y()_!^Zr zp>Pu2gz$YbOz=zsGWdWqa0dw|aV8K6=?A2kun$UMYm)LN%o{>CA;VEWQb?FG1TbOL z5ciP~Hk3|6>OmFH8T2ptZj5I9_U5~_@#n-H2N!-SF} zfDF7xxX*-JI1`A3lr2(BI0vP01gD@R3F}7EO<CZxQUVM3)*KnBG|xzB_rI1`8jbWMs0H=q>G;1rZ3Vf*MTOz`lN zexI;*G+@HQ(e5*0u!&BB)h5M+XcLe^ca!oYG#f)VA@r*Z5^9eDGAKXBeI~rcnLs3j zKagU=Lnwu-I0Yq1u#BaffZoY4Var&+gjHkRXTpe|vmoKF6ccnm11UuOtUL*=#?eji zdnm(%#^ZntYK(KA31~dsgwVYB!YXRp;uVy_J)DA)Bpky-hqki)vdfqg_KXKiNE`1y z6UI-Vo8a?F3JJp|04WTbpgaj3C(=nseJq27mJ@*t8ccMb33(>bO$dD<#e^?V3Rawg zk|g|#hYpc|9?3A_?@53OyC%8Mgc+0RCRmV^%hA}$Knh8dl_#O+|FR$XX>=0OZppYDb(;oc5IoI&CX}5{HzD+n6cY+g2U5r}U3n88;Gsh#`1!~n z;R=+&Nt}T@KGa!0gKk3VdnqQ&odK9Id4}>P#HY|nNS8A)ho=A;gr&HTgsQ*LO-Prt zcU0;ZAcg$DC~v|`JamWzCYKBn?m`({#2L7Qg!MD&CNLRNNJyOtm@sRm@+J(Ol?4fM zwk-zE0y5}3%Y7u&olQ5v=b01}ew+=YP<*!XCVa+2he!y|CWD0MPzJYf2JRr?&pC7x zRQYfwqP8u5p97e%XpZtGjG0R(0p*Zkf^ja8LF`=jkL_p#kV3;n%9~JfG2Mi; z=Q2p}UJPV_7Q4@cb2t--gmlLeL)7Z%2$aHKI0Yp)@Rls0n_zt@!-Sbj029V9ai0mj zQt2d^tWqvV?Nfmim{jFSsI-)BLYkM1C2FyyKn8i1y3d3gI1`8jm7|8%K#H*EOVa;(aY&1FdwCm(0w_OLfhralTdpF-2_t}86=cn0c22Q zh5Jl+h%&Fk#h7z=Ypcy3YjNDmn>ipQVrxu?k3` z%PQqbXuO(kLP~xaCe&CBWKeds`%HL+Gl575FMu-yto|pe?iTH1_ zTGjZKy@aFaI)41zT`_6=rrX#FAB0dB(y+bO0kY5hgO{EA1DhV9VcG4&?h)pR5bBT= zAF1L0h^AnqOx3fy|0V_X1cGcfTe+qix-y?hLA`*W*bC`{9vA*V(WLr%x+W^eQ9UQUamy=Jjebl{QGwq##1!o>M9@4h5W#uUHd^eWo_n zBy09xK;qoNL&m#(in3oQjqa&c=qZu?oN0ik(>D^7hCD?mVRk`t1@i$?5ag*(i&1NR zrc`3ylY*c+H&yW;lGySxrOqpFqHE$;Mo{NO_DgI6G+CA=NfYj{sxOd&AWirZwW{-N zBJ>1l;t1mZB^^ySXQ4?WfhI)uYi$NJ*-jcMR41O}b6Vyqu= zZI+-(gEW-UuuLHfNe%w^h&6%OPbnpu{il#P8Fx~Hnj0#AwTdu#EcZ8)f*?;*G}8?0y(=-VNkMR(t47Y=_+~HcX@zZcO;BTjCPems*am2_ zc&j8$xWlSGOA3NC;nT9Jb8jQ`1Z%?g#0Qg(hTG|yB&Yzv5`mp=hdC;UlJ8uAo{m;JiEVi)yaq#(%CNgJbg-d$6kv66zoIyYsE z{NZLFN}ZS8N!LWh2w&t{=}n%YF*DUtm*X28=? zW`fd?r%3hT(x@qI%v(r7kf#|h&ZLd3TakG{3WDmKnG$h!-=8libzXEIU6Tyq^^nNE z*FHd#nHDLU*bl4vZ&DDXi6iJUDG1WU5ybyXI;!udYm(AZP$xw8%j^dEr^62rl!n;%Ku9%iW`4^?QV`@RSENn#C73&;Ajng$r#=5v zpmvi9|hrR6b1CB&~%& z6C(R14g;DjJ0w{Xgf5VR=$asu?=Yb!x+b*a9@Ye8KTtILmmqOY;32z%{f~dsJ+%t& zZHeqZ{TuLf$lnB|A@(_qM=#IM{6Pw$c$yKSFTrGxf@q!=I!R+c|53UomimG^C$jHx z6wu^&DMYDen66XjWvOCy+dz|j6rKG@9BKr@I1D+a=6O^X0kI;kN zt4TpLPaB=D!(1f=(LJ^9gk8<^PZpX42s9zG|K$Xr$%GSa6C`bHSuEwnh@FlkPc`vHeG@yeBD{qf0BYAO&mc_NI{S$jv% zlj;IZi0pfx0W_I=T7o8XPuiBuI#HK7P6~oFdHB}%3F3_WyyzvEU)QgZ*b`>7J%L#t%N%ck?XZ>A_#tkb)pj zXAe2icuk86%)g`{$Ww$~b?>`OLt#JLIl3mPg#>j@WdF^-fF`5x+6BPV zm4^~M$Btc5TwbnLP_Y&Zv(^bbz6d`mZ@R) zl4Acc&maXso~GJrwn-_HmpMoZf;>fNYTlO(np5Wemv`uzm?{Z0A+mq>4xowdjs#5{ zL@p-I>|F_(l-`)bwBntL`I8g`X_6RI zk7+x;IP-)Q1Zh(Fey$$rzD+3XAI6$M>{}hb3zIebJMRJFth?tv_AlS3dx{*NQ-JgS zKlg!Qce^ja(-l=p1iufts-8j$f;^q4X*r>Aa!$rV3W7XEXxtJ*;|7#D?%4ynCaEJfe$2T;=p(bDG1WU5%e!92-YMk_Om^rYm!h)pb3%vHxB_#Mm?0E$%S); zm`bH%E}+28gE5NFLJ z_pyKeG2K%iUxBB@dH?8RVA!1>OYoGdJ+toJ?un!z$Ww%n>BJqx>?Q?4o+5-)?Jv&X z!$U$k9zCIJk|ETD$o{n_fF?0dBx=IV#tTS66iw_w>7*cvCRxn;U!T%7Nr({C36cF5 zPXSGaKb5QrLK{gzbWIStLkgm6LOb?8<28ZU4<9O;{Y}pRaaKHYANyyX(>+C<1)dVw zKlB_Jc8BK@JPmLB^4=>U)L8%>W==KXtCx+W%# zKocVSm#ly$kyZ(s@O5WZ|4IsiG;su-AO(S%*bmy8|Kkg~CTY@#}N?5}?bh?Dx# zee9onMfWr{T;M5@{e7>1VYhuH!BZ4kGbXOzO!H_`5aemb$;as*W_U7NNkNdO$kfN{ z!k0M8{r;`jbWOrT1)31qKld8Yq~B{PnqVSlk%Ayi96?7&L7*nMC;ng3@%9Z}6Q-*` z6C(Q$-vF8z-bm2Ia=hKb_4PV1t4TqSCSzlM-M_VSF6JsJ2-3u-$-guD-!DR8fBRcH z`x)Itv%mH&AkM|cLR*Mx}_XhLNF^m{;)Uhk!7Vn3|v8KfXk6C8Aq6a;F5 zgZO_*$IB0NO+rHinh@E)`vK5I_d$XtJ_v=s>>j`@Cj~*8RLYBx<*ZeGkrV`J5?p2I zo;=UdMUyP<_n&>CYl8X(k?BpUX5VVFo)iRmno@Agkb+ZkGAl?ykf#W}AE>EDyWc;P zgRY5RCqbPP**}y6(4<2SDVks+eOrI+$kXtU94q$D%+92ef*?;( z%KIG0y7i#U`zLeLHA#&ZXhLLvUv5B?wz;Kff{7eW3W79o1Z^b+ftui+_qEibwz zp*;nf5ZOQH1!&UGOM)iZ5i+fdZpX|b1woqZ`Dz9bQ8cj!rICUt znq)EWU-zbKk{Tqa6C(Sky#Y;nc}vy=p&6tgx+Vx6Bn8nmp&g6!)7ejGEt>sb@&n?G z%kMt+Hy5CL>XYR@|H=Zuuxl5P;Hl;49K(|WPt;MQAjng{9M6rr7L{Sy3MmNEq-{22>ao6n#X<^#G&wkQ;jLp;+f(NK`Gx50 zr)Wj9KdlfTj;WCQ*xyi??rBONfv3cIe`#T0*wqV5@DzpH!YfuCuI^6?f;{zGx2pR5 z!5++PQV`@RGUbeXd0R(W^Y1T0*CatF(1ghTwjzKg{zar{f{9Ed1wooPg4U3NKuvH@ z{J*5*{10?ZRP6sMR<0*Qr~-J~E$lLn=I z_e2&iMqz($Q9AqSj_2aCex`SFQ9zuLMcv2#@5ShzriKYTC9=P$7%=S0#Uyx&yu1eA zD7i`9n-m0j8a_*VwMXAszqTSl@b2#qEM(KSJ6 zD=CPs3GJ9(md?K4Ak0qI^ZuB!fH=mo?qh#hIl8A-;k_-9{W;};VV5l@!P8XFkflXu zW@o}kL7=DA`&T|xs1!4a6a;#@I54NG?s3ZccDstMNqAqu^^nN^S{0y4U6lk)_`0*I zV@W}vCicUsUPuZ8HNiprzog?>dAcU19s*5>?C&WLXcAOjf+k;Ww*F_=SbuDG1V}_rXou4ZCUg`~RyzXJ6GzH2XhQ0K`eC;6C;jSEPFyK2YE(k^NsP z0>ds@QG%yvN2lOT9apM5l7b*lnMr+9TVKw`j3Wg>o+8um`^6U0-q*Le5?zyY;WKPR z_E%N{G^t%liYE5Ms*WNBL7F&%=8=LxO>j^Azog^vk919}jyebD{hdDonzZ~;f+pOb zUJk6;g&9f;f;4&e)i%1{mBP$AQV^s`y{jMmU-hHi?@y>qXWueFH2cYw0de9gyN~_( zRp_2tdS}J{v?{=`i&l}~DVm$>!m+L^)$K?@kf+S?D~FrB`k*$Ef*?Dn%3fVO94h1wooPf@YI~KuvH@{J*4Qe>J)$8Nz!*;=I4D z8lZ`PH3^!0w%JDiv8xl4ND6{9dGg8DUwyj(vxXD|Y0^0*Z1&M`+Os`ltJB#x8AP+6 zR2>j!Ky~-AKequH;r`)IRJGx(Q-kKBydCC>(@_Ap>BS}G! zr`-L%YC>1a{r>MY>6)Yr5okhWe^E_9lgc%vX=1+%?@bD#X~J#WrI3Osnq+amzqb}$ zleBpPO^EDoss(7$w3cK|5Ym%^=$at3f)qs8gm#RoO=sUaMl}0_YXjm$*LENKGkxiv zS{DdBC9*%>7Z`SaUrC;tZ0j~(-Wx~?qI+6_8Ab}CczW>g#Uqrz!M)0lu8C!=KocVS zzxe^0RPd9e2~T8qQV?Aet9mLah@wdr?C+{W*Cc$LKocVS>+1lTG^`^*liJ>O{~p)y zt$GkC2-2ih;r*))t12<6q##I>qt9*O-o1aJd>%BsE}ebLLecEU*9F80uj@Ycr`Mx< znz2IQDUtm#^?+gLsVBixgpi$mH7N-4l)os~WsIaC$W!k5E;{?m>eDr`%n)coWPeV5 zK$EidrD^N*TkxxL<*v4k_G$Q8_+dLPZelFWPfb~K$E%+BxsUr!S4x?yF8g# zQV^ucmku`v6<5_~7LtM>O$G#YYThLE1m!+xNJBdNsY^w(uWbm3)2E^P*#BQ6x~B=t z1fCMv|EUo$Y|lm#JmoP)dzz7gAW!+A+Drl|2=bH3YiyPB5@f$DDgvkCcjR8$c zHkPc3Ro#&kMAyWs9!CnIYeM^ce{&PMCK>+|XhLLvWfMS?+D#;A@_NOioJ*E%Ge?nv zAWaVca_QZw-jyx$NI{S$1?Kx0F7KF1Vc*b{&OVwTnte@EK%5>;-N*ifW^_-P$pTM_ z>?bz^hMldM1W&ttwT*7~FrTFnDG2hk_-EVbQynWYaik!~Q`7uxrnRGKf0Ju|bGjxz z!a66iKdm{SNzvvKG~usOR&_g45TuDC$V3W)G;sv+|B{XkE$Eu0O%c=yk^QAD08Og5 zkf2F`2SP8_R%QB=f*?&E7d~BX#g6;t*`y#ylOxw`qX%uzO?g+R&Y#YH_%EW_kMIY? z>EiD`_Q$H}o|>i#JSDQ9qy~ol6%V@#LdYXDjQfrFX!vh(*$iurC zAXZJJ-jAdOF>3mBH7WX)s0p?ASM*@i#G{9XnhY4-BKFg}9mEf5L9Ckm zG~xB7gE1a_eHPHVh}BeW%}aE?s*k?y}z&*UX#QN zL`|r@Kf4#BCRKY;PEV=#b+jN>P0Wp3q>G>hp*2D8`)hsinmC;yYC`S(rM`@sH1O3> zlm62?JZjUdqj3N&h*gu1d!4D(Yeyqv94&}dlLIZ<^zK)wC34>%*&FYD|1+Nb#@Pvi ziqG_Z(3?@5UcFyl?@#T6n~EnPf79o+sJ$Q3hmm$Mq^+v=jsM+f`0iKbjm`Q{E(Dh8 zrN7*RraHYY2GW99rb5+s=TzT}eWv$wKfET#Zxc14_Wle%MosMfD5s~?`(0^4teQx@ zA5IHm*5t*8J@c>bi`S&+I#Cm9?|<2sQIpsDYN*M~8jl)=O!pJtqXn^Q5)kyP;cr*U ziSuYdteRY2Q0`dLx7feQHLM@r`|f8|_x}6+7{%${@8$LWr1x;sltRLk+WVv4W2Ai- z(pJ^`g8wh>AOF2E`;GS~7Xr)Fz2&<>^G@1{0kj~Nsp&Egol(oje7)1QSbw}G#s@@A zsJ$QM&!~x=Kjrk4djB0-5UVEU6Drb$(t@y>;P?HN?<>^g98nW$?H|DRIESN7UOHvB1y@6v);*NNlAI>u1l&FpAe5UVD3|0cFwd9VV~`-284 z^!^{Jd*62uqc~oJUS98y`w%y6d!8_*_WsZh8EIdKwAJ;#Ah=hbYoGP{hm;F}Wor71 zzeAQi)%nwcSf+v?Tx#@BZ>0BU2H-W>c9p0Jwf83mFlzEIEmPKYF12x+0BtpSaSIQo z1tB$2xbG(o#%q#tk*Eo^_va60)TH`g%IV=X5rl5EAmloEu|?8?@S0#-|BvwA4|=G& z_j`QAC{Cx3US98y9)g>SmkCp9?++frNc#$;t*ZB9{`_uD`zD3ib%szb1eWRYw1&dj zuj`9`v>>MG{aQ0S{$a#Es~L#bB<2}W6Kd~=1u|;#kd`Taofqj^1!|~?`C={71<`_- zHF>dNulE-Y#cOiu3Q-ek@6R5}s7ckKl+$C?G0!iid{#q@ zparpNV!ym;@o$^oLEh)@Hw^Fnm}{zgUq6gdoc6@Zc!Q`3wf94U z7&R%TWy-qFrH*VCq@gBKP#`S`s|o(h|M>{KChm&w_01T;sEPdu%IUFcqKo@achz%% z*p(K<@VmsI4`zO6Iz%-?$?-uuSCRQJC3NJeqmj(mB&KkQ@N zH2e;6ol|@N{f`-GpM$j3^?qb4VPl z%s(j@uZehpGX(_>EuXhB#_@ZOIdh1bOC9#IqOeLrdx zqb7EvD5uA&$%2jr*)a#a#CK>xtn1`?Rx6{+q$}B>v>;YZe){mA^3MO3LwdjGXuS6? zNi|Xay*-^rGm7Im`sMZhM`Li)ZAFABwfFmuVWfQ;(pJ~|f?#a6#xbkf7|MmfGBv$P zFlktMQKSX2Oij)4eJkws{`j$YO)ixXHKF$Yh_Q^C+@fX5y3VCGZa7w3OHDSn+7>0S@jP!sb7RHXB# z1u<*#V#8kV&kVzB64QjJ3AOhphB0dLFD+A6O{xlld(pXf#WrCYY7+VEdBf=VT4FFQ zh*gvN4?>TwdZRP)df#U}-uuSpP!r|ee``FWIE}}@yx#9W0XJ>iiZG@2evb)^w10uL zRrS7bc;=q@U;LdE?Jb?TtaSAXZJf9$L`jpi@ocnZL^W!Gyj=39WFU8DlfL5Ot}zPrl#f)1p(>( zkr8-Jg5Du&LhbzzA{aHfK+BYMol9+8D}r)*teQwcy=XyLP4M2IIt8yuiak*iYVU_k zVbr9UmMNYn=qyJzV|dn+6N(Rb-gbLF&8IS@&1n%gk0ywAvG(CZKqK# z1eU4kO@gQk0m$Fu8y1PzMD!wRLhb$cBN;V0N6VCTol9+8Ba(7@NKIa}ad%n}QWJ&V zpA?1HWSb9B6Kd~|iel8{E-h2MCW7!rl;)ZULI5oYuL-ubn~wK>%wW~M-()(YICZDL zyx#BmDQ+60BTT8i-}zHU+PRRns@`|6<8tZu%@xE)v>?`X-qxYkrIRjhqUWcS3xR1G zvr%X@{|NGT);@~HYZCMcQ4?zK_l;)My{qch?MA*;Q;fLqkp8{!EDZZA}evAT5YhlTNpe zysj_SBd_=0oQe0o`w-Q=-)JVII4(0^Uhf-b;imo~VM^`&4zn0(?}fBg^}gWL?cZys z;&gx0f>_si(4PZ^DU0mI=Cddl0?X8NnHSr6AkX}RV(^*>1BjYXd*3&PQImXHrmX8+ z>c~nll+$C?L<;hv1z|P8pZUkl#%t2H2T>Dh?+=~LsL6F&rmUJ=7XaM!?>(5~n$7#;X>wTZOxM}!E!j#(k zZ_Q<-y$8}(*ZbF2tf_ZvtL`2xh;^O&?|nRE2hV5J7 z`iHyQ#*aaIzh4|)lS>~GHKF#tK8{h7qqIy}*SXZj&uKwOO z4JB$q?fnlHFlusvmMLBnL8!HWa(Z}81fdr#2)RxaHjmHo-cK2*y7y~;&L~dh&tG2e zcl-i36@3X)YVWuBf|2%iNLy9!yMJ6XyrQ=t{zVI7nY#ael_~GJ>cHwfDW_88tab%M`!Pi**0df><>%U#~^Fw(%NjA_cK8_F)Nl zO%jI^HKF$Y`w5JioTFvRs>zuHIoX#J>WMWHD5uA&$-MLbHC&)~HFl>3v96O@HC&I! z_v?qe-fyrF?|rA#LkZkru?dPJ-?HZVN^)?`X(rM?k?DkVyA@_aPWq9xV_l24$ z_kNXSjN+6)%I(d+@YdnQFT5QTGC5>qNN7kz)PSmjAP~DI`~l?zLD2vI)nmROXj{v# za8q~k`#H7u>wm>ad;KyB56jf_x9WSearXX$7Q`|&b#eIbg6Q-W`)!A-?){1@8O3=FDZh-~Z~8TEdP(uV zU+-&1+G|%*c$7?krv>4r9-_n7lq1=0+9esU$+l6%bx!U5*2#>T?4o6g*Q7{yn-+xE zq)6wUthpxG&-eSS!fTS~Pt=6k`}$RknjEEN%BsnuvoVXGZriVWP77kyWN!7h&mB5m zoZWtvhMKgwbH8ubn5oD!fA!T0z29GT@0VN6D9!^&`DOIJ#~R$UNcwyN^LKUDUc*Rx z^=e9`S*Fsr*xzVDEK_q(JF)T_%8_jE{f;SkP29&4*EzNKTcj{*vYnPGUXvo-U$h{+ zCPg~86wNikdcXHKcuj(a5jCOqzV|nbnjEBM%BsmfheB=~-Eva*A1#PglWxsc9Xog2 z&e--F4K+FUv$0wT+WS@4;=NxaT_?)V{7+fMDT0(=M(;QH7B@XkevXCu%wO|chUv<+ zluENq&23yc>sMM3%hVk7rdZ)y%8~HicSoN2+pWWEVhkj%b87E5S;wf!54242niT1- z(t_}s6zS@&(_9m*_j`V)P?Hd%Ce+^V{2ikvxwK4KHEH=_~1+i*!Gp_z$ zqm9jsp5JMxNu2&eufJzu_kH{Ic<;Ae3^h^i{U@yA6hg``qxWCifSZcpgekT69XBvc zm#wE%nq@j{+DFUhPHZ6lObcR}3iUcXnR~dNQP@B^607%PvcCGWa?K~m@9cVWBVLol zc|=X9z29gfqbA?eGG)~yZ)Eisufi|Vf|xZKZVqzUsG%mmn*PxwwD%30@R|h8Cu&0N z{SKQLHQ7tclvNYQv_jXfzw{FSrUkKT^39&c>;Gv}pliNKLrw10?sjlX$I-|$zuotE z?{Ax=y7&KK73T(|{4#pqbu(@nvyw2S_I{Pk4AZ3VDV1iK3c{~j>-_qz?hq}AW%^l< zShoo&J;V}P5UclvUQ3gTro~|If2QI!ai2rfgxdS{QyDc`zgbgF%pLg$Er?YU^RrNq z&MB30BxX(ENap|2HlHncO~RvznoxWHtu2h2?4f1Kx=tQO)&98NJAI7zXhE!+d~TO; zUnu@r*LaJDnk?+IEat-;d!+ZDK}|dbL2%ZO4+$F)5i((Xw<(jRj_Nldc$A;}BGtWr zpH-Y|kn+puedn#XY07xQl-m0hw=zr@{y?cT%T#dpZ9OS)mTn&{h-G>;FW2#dk9&xZ zX+g~EyroNvq?~ogb>4IvUK1gVs0p?A>uqDyWbIZhHF>cW>3*jLv1%d(Ic%dGiCGgk zlKH>1t;>&iO~e^QO{l%!`bS1hcF{6rT_*X~JyX?LE#d#0Rt>_!C}}n90O-Lhbz)KQU^uot7!(df#^PVJAXZJXn|*nB#`NE_-G0(glh8`Pl^+n5k9pb%G(l3uAe~0(AOuQz?6`%PXGZ{5mmZ7;OMY^A9 zL3mAybV4TONbH&@_5Pb#cuf*lEA@V(EJjVfr)A2zP7X}}W&XVfC3`Q@f>NbTjnU#<@V^liBdttPb*9S%^A z#Hz`>Hyo=@_q0de>$?s$VfB7cr0U*3%PLMDr2H~^|KEeSse3YEO6~nS2N|YQ4^k@4 z?ESqnw**{I%-&23Vwo;p{&UXfgL{aVXhAGfp{Pm05B7=3dpOk(<27-bNYsSd`{fQZ zYV!FZEj4+u73s2RL9CicK@Vs_%$mTF%>Sir9!Kz+1g#-zLhb$9M;J9(eON{|Ic3-rsIF1R2u1h(_gU5 z{FWBPGBy28{3(0g#WS=ZmZ|y5jzQk%w?B^88_{nnuO;QHKE@3tDIugBc~pfglLgtv}c2C*17P`^7a<%~aEJrr8%C__bo438uefUqujv zO5I0|9x){}0`5tIFb^gx3W8wYXH?XnQImW()ewYZFy6rw)Mr%Gz>u&}p{74%+L{Z3 zuyN+TA*TQLe;T{n^xwyy_O4|*O3J^E6HNc@6?NjM>A#gvn~&Z|5Clil0Y-#Q8Pzj% z!ib2`(sC{@7BzkL)%wdoggW#Y6{U}enA9_L#F)t;WMt(L!vB0_LgY|E5S$>g`-q4U z=Hr@=CkXy8j%(g3I#zTfc5U8&LgZWnj@*CL=x!6HjE}HN+f*C*m(}+04BI>AHsT%l zJK`MylXCAY80YqW3=1iF8&<3r+`s-#XwDNeJSw>x9GRJ3`gLS)%{-z0M8 z^S*wL?QOh*c>A42yn|s_+zY_|JD(?f+w!ZnbaP$Ujf+pCxkU^FCd`_71v=czgYUcn^e0x%Vm< z=k`7W3n_RHS#wwybLR7=DL)iQQ>KzY}>byxWX=8ax8*Bauku#t7 z!3%6}@fPCkc^>iZ4wG{41Q_S`J`4*fc+2nIrhU5$wt7cHWZ8SC6FKvF@4AF|F9|UH z6RQICdCl!2;@uu5<=!)3oZCAM7P7&+m!mKIO9a-ULTBoi3mE`YUYjm^5GZ z^SQ%i#Je#}%Duy2oZEXNEM$ZC6(Urdci@#*<-G!q%ct%jr{ZE{sK5Mzjy3)wzu#j;#~+SP`xYsN%!sxvcO)#N;Qe+$WBvDyU5uOm_04H{V}6d)@nJdJiBN6c zo;S33pV_t9%5(Qe0ap8%ue3?tA#h}V@6opq@4bk39;86^z6O(W@76a<$$Km;q~J|^ zK3_|OYV&rxrNvu|r?g4F(kAT>h9mQP4=QAP3mJ%aCZs_1J_(a@@A|h($vXfRQt(cA zTsuATP@VMh9qOdl8dW=e`VY0!lZa4l-VTL4-kWOF=p^|`o7#O}I5NL?&%12zOS=*8 zR7ip9y&op!-i~)l$-5UUq~JY2ps_wYps{{nKx2JR`0pGdRGW7RM5=o|_URj4_K=>h zRcm0iZ`#OtY`^nebKUs8I~K9MjoAG=8B(Bn?}SOY_fr_>zJGVRXDI;k^OEFR`9Aes z@_pL4vcws+7C$J-_gfnMyUc1| z%lG@6M9zHP*PpPx!}q+$e*fI>G2$HzlXCAZFwX6L0~S*79vSp@PT;2IId6Armeb&5 zo16)?ymCCA*y^1Ok?Oq19WJNG?$3tM!P`WNvY2$OQ} zRWQ!&eFhd%@ZNnh(RkY{B0F+TsMw`tj@Y2lIMMk(TfO5UQl0l72Ob(o&po?NSnZRZ z(nkJya{dUBGoSatr)+Ph48+^B1o7?;lXC9_80Ypr3=1iE)1J@mp4#di4Uy`+NiS(* zc}g2=KAp&!&wJN%w)gR!h_~A_#JfFA%Drd6IJb8iETrJwWV&02_n*hK4_maM!)Gbc z9s7T=r(-b@s_p(A`rLfVws|j38*2S}eAQ>x`^ft*o8ZW%)8+GCU#`4h`b+$@&!@KC zi+DQ-<=LN4Z48rg?=TqW_TC5!DR_s5x$B38x$Ap`x$9epx$8Z`-1S$8P;K6U<;JjB0`>Xa#m-zAx%W^Q=k{I> z3n_T7i{7$(SfFlq@4c;dtsA_(<0_A4@8lDq+PwYBYw=zx2E3&=Ae?q(qAqA>;g$i`9RxkRWoZ?B44yfHs%Bd-VS z&qu+L`MsxBVtYINhn3Q`zg>mltcc0w6yxNlSP)yV9=lu0;*Y>GHk)Zd#M=9kdPkd1ySOK=ob+ zlXCAnFwX7W+{sb^#GCefK9UI4=3M}h>bx;OX_GvqjkRB|rsZ_`yj^Rty~Pv$?4OrJ zLkd*yB`_)XJ`dyE-gTWV1wg#h>VMOv@3EtMHa0$=(c_dM^Lq8r%>G2EHt#%$ROdaY z_CHyq-<7Kk_LBQw`rfvhH*MrRxnHH0<#hSH?Q65Wg;R)kD5OC3o(Ge1?_)5|?OoZ$ zQUJvJ&37I3jox+C-|FG0pVZA!e^u|OHxQxPyfYzEo%iZziB|8Qt-KqUNqTn6nrO98 z`bwMh=bsQc^LamXWqZ4yLA(QNn=4NBj(|zIcNUCudq0MS6rR^oEC1DHcn_DZ=idIk zON~1}b@8pQ>)OuMa;a$ZPK8Ky-g3W9e+^RYD{YeZO(JJL@9TBh-ZA-zw_hE^I~XSA z-dkXt+xrGAq~J}ve|yxm)jJs?ZS$79 z_Ze8o25;xrZ1s+Z$g=l7LgdWneb9~VZ9I>7d%li%cZW&2cLI!admn~{Z1A>ov(-Bq zBFo-8oyeKbdshRtw{Q{hcB_wgw}(l&_Y4^4_D+L^6ufWET%lW#uum5?JV6(^FHAT2 zpC=hjgD`6X$S?%$i>$fncf^Iq@H_D;c`&m9^f-i={W?i~i> z+};~uAqDT*-E_v*olj(YT|K=wcIe+e$zzA;t`MQxyaU~}cyDlj&FcM>*fvkC-cRe( zafQ`Bc0XSMN9Oll=E3$3x`6a|38X-MK6hzku8iD!D2#J^FNcK`yubOy&7xr#{8sB`hG2Kto@O5S5( zAqDS>wK_6~3LKKuRiOh|$1eG(?+-t}9Ql6L?sq~QHdT8Vd`v=Z+) za_>7Z&h6d2jimq@y+;zE+Pn)Ovh2O&h1_KZA$?V@6UDnbQ_BI>#m&sM)&=h;kp** zpZXYxP;K6s5NVtDxlbBey`Snmxs%mC=KX}ona}%S2e$X|Hi&m%dvnF9-Vrb<_s)WG zZtusikizp?tFA|~&)2@5ee=yQa(y>Gxm3f{EmHIH{}^-hLJb>5ht zw6R`)Nt-l(mdKgU`*dfv_qJw;w^t{`dmv28y;s3FxAz%XNWuHjknVfV&FHb``N{5k z8a6TP`Kq06k8@{Rz2hO$Ht*v<_p*BbrFrE|R{N$+@|8Ae{|J#YpZCG8Y;Py*`P{P$ z;@ur4<=zP}&h32|7E~6w(@LUaMSAj)6pkZTkVs+(kA(D zf+L$wm(P2>j_sZJCgSbjgLpTFNx63zjB|T$goPBmY4`6dM5s3JK%EwE%um`RPibTA zuYe=-doRiqyF z<^Ap5-CQwl??_lk!TXnx136Fr`6Oprr#0EV2K3Z_QIe|PPK0Xn_Uxg>`^w&}R{!4A zproIz_G`}GY_)INSl`b>;K=;mqu*tF2YDmjd5{9t`x;Ejy<7JzCGWAYkb<{Q_3yI} z45%rdby*`8^!ZC%xVWNzEfK2C+wEOV-p?|v-Y-43dx_P)_uAf8`~5SxBX*GB0{x!JNRnx zPMLDh>ix5M=dW4qKmF#Y)jsC!3rFVn?%9X!?e2wmr$P!;@BJ_-_jc@EO5VL-Aq8*R z^Z6ViRGW7RM5=o|hWSYw>-)E~N%NiinCr&x-LWs*`;rdvPKFey-aBDZ?)?B2=4q9z>SCca`@or_1MUKY;BmV&Bh0AqA@UJeZVwAA@mj@5=ox z1wg!M_iqCcs?9qSBFoa(y>GxmHh6msvei2oBFoJ7cn(IqyThd1I|0VIy${1eHh9~8WUF^HM3%jGI*~J<_pU(1I~MVF8-jSZhe^5j z3>fG3PJ@MP@Gd4owcWo%1I?#g_THP|$fncf^IkuU?Oha)csmS5yc@%$+&c`$xxF{S zLW=Iu4|Re49jk@>x+2D81}&O^KlAO))T1DKTexA({9ig9~K!a@q(iQ%q#`PX(L zRGYVF@T>9;fg|&Kj~>nTKE4p~&Vv-F-q&DK?%jG+DS3~Dg%rHy_ioevS|U`Nx7+Af zKL1?_@}U z>b(;t<=#(WocsRW=@Ux<(4Uw5?>31D)#hCYk!A1QBGhuae6PQojz_#_Bi`|l0@ZsR zOv=6Qz&N*e^Ds*RGzAh+(JMkyP+iNP~JrE}4-m74o+xrYGq~I+GF^lA1&eLr5j)%yy z_dY`8%;$YDitX)$^|xmv;@ur4<=zP}&h32|7E<>9pP!G}McL{d4UuKdjId1PlRgo_M7#pycfWc`MqOjv%QaJAl`+L0@b@h4BfjgjB|U(!9q58 z=MtgXyuD_>D(@&bGQaoKxoq$7OvJkYQlNT2fJu3Od(SafjN3aB7P7&6I}xhQ+jH)# z@(zI`^Lvk;&-QL>M7;AL1*-Qon3Q|Bo>xlVV__jh@Be*1UrU5)^LCs6s=Nook@>v` zea7~7N<+LeAqA@UNtl#-*N-hF?*Ldx!8_%HG2*0wW5mq^#)xkX7$a63Fh)!wLbZ82 ze5S=a{pc;Le^2twx0YG$H+FHe+Ba>|-~W|1Y2O!)%`6qZHt#}+ROfBlBrnsJ|6?Dk-?uio{}`)%`JX5ETYONpn5NXNxAoV80Yq`yUvggvkMEk?Y9VN&kB1;)9(Z@@wd-plJ>^;)SL ztgCo@Y_XJ8=(Z^ON&`VL!K>L)L%roUV*L-hY@n&`aDR_}O-ROc=C`({(3 z)$d!Yy8272efgg!_m2=c^LZa!&h}2sMZTYVeua2p)1X&tj_zj&JDd-ex_}8`E#n@f7t{_Hk~e?_xfbE z_wjv*x5L+ncVn28dxya|xA#U^NWt51r>5SusHQ&deog&n_iO4?ifZbw5TV+<1CzCQ z-|iWMdM7-*ZT0Uy|F@4aj_;(ZwLE`b!N&*v_y%$1RQ4~21V@8z(Ng7GE zy<=0@-cCmm??Om{>Rn+C-McT0b9=|ZLJHor`*$u8s?FOgMTq=8AE9N5VojcyA{{wRwB4eO2BeaAbb((d*dWK{E!i ze_oOYDNwzy!KB=~^|z(uJr)+S!Fw$cs?FPN-K+8*3`geo9<(0ujzqjOAqA@UNtl#- z*Z;1RyaQk%1@F#h@9U?HxT)`4=c3+e+Ac?TvY$Q zdtW#*zjx1#Z10$uFE_`R3adX5SW4FliIm0_v$ocW_ zXT~{1s5b8sh*bA_%wwg8m3PYK`9{|LS=w0hoj026#_!$nd$zZ68seP{DNwz4!lc~$ zDU5U9zdLQR6ae{o$;H3R8M-`bV94M2rlHTS)`po&+zgY5P;K6Y5UI{PaeXuN-zOOp z`@QP-Q(Js*IbFWj-%V55-tN(ecRZv(^)a_>7Z&h6cNv!wutH|_a+BoV63y8t59 zd7Cy?ze=0h`Fg3A)8+Ga{ekVB5`}n2Lkd*yB`_)XJ`dyE-gUQF3V?WLor?Aeo<7D$ zFMj0HyWs$z*~j|&^d~~KdFMf-I`2i>%4L(Dy3Nb?lKY1AE>`>4^-<*q%jxoY+izog z$4o@LLm>sK_dJ-Cdmn>wZtu!lEd@ZlSJb|$FYk0!zr^vXez?O`eV=Mq^#&qTn|CHe zs`GYU6P`u-?wffolic@w7-zMQc|Rd?=JS5|BisAZEW|r-o4Mjt?+BQbduPEoxA$XM zNa1;{Nc`MuUcWEAs&yXZwJ*xv>(T4pUE2LKiTRX50Pc>eT2xF&->tRwzm+0 zczfE^|D#r)SBqJ< z$ZEgu&Lpe%W3cb%o8ZW%)8+GCpTYJ%9*^|5!yd%DF-*$6!(g1-dm}8Q;C;LNGO@u2 z--r{Y#*1!QABtDM-lDrgglh8+%+TU3_gfWx*y{b2rzIU!d#`{a^LsDLVtf0~N4!fQ z1?uy;OQyLpa_^xq&h5P%7EpC6BFB7?aQwZa(@9Fncq7$o9(@A0peWi20I9N!*oA!L3 zON46k_R7}cO?pY2+UId;lm2`Z9GTyHY7X1mX(8fW04Y$tAHbx%zrBs-ig9~K!a@q( z`8j!A_E%lorKI+XE*Up>bXlf5)nz*os?FOoM~nBz`*YCGuar-|jDG&bv`O9}aAbb( z(fiomMV}+yd5{9t`x;Ejy<6v&lJ{6xNWt5^?@|3wzoYu3K1cP{`yAEJ?{ieYmI&46 z?Y2*gcgmMttlmEhbggf-PkKt5~dP$q)Cv9r? zJ0CLFjo-WD5w>??EaIIEDNwz4!lc~$DU5U9zdIea6ae{o3C(*F5vt9*5F*RoyTuX9 z>GHk)Zu&FZ+i4!+9SOBu8<=)3&oZGwd zFO~uz-geEi^{=fuukTTGN8jq^ef`c~i}VH}RGW7uM5^;H8Nb!adv=$)R{NN*v`PL? zh@APnA0B6WhtEa41AjGFoa!9`lXCAY80YqW3=1hduZ`OpZ^*c|z|cBuw&9$^L_^(n zk%o51EtiTm?^K9X=l$8`jaKiU_3mb;x}T*@^1eyr%;$YQpY83x2=Vqifp`bQq}+Q8 zjB|V6fQ1yiY0qmO`L=o|L!>%y(dligx zd!K=Y6ugJlvop%SoKM>79S@Nzy@O`|XsfTZN%2RBocX*Do@RTyuSUE*Pa)pjVN&j$ z0OQ==hhZTF?{(u(>f~Q`r)~9)hDep(rP$x;M9zHPyUwt^g=L7h+wX{Xdzh4a&wz1m z?=)CQ!Mlk^qE7x*OoVE?e}|qipR$eKjh)_-`t`*o-$$;GO>kt>>GFB6KgaeCT7!5y zoJG7F!=&6h492;=H^M>+-n9Go6(Urdci=fLZ^TpDtgZ**&#!XaM_M0@b_1dAfIB z80YqmgN1DH&Lu*%d3#-WRo+o>WPb0dm)PDZUnAZHkOI~F0ZhvK+xw!qV%*-5u#kfH z&xvdG#}e1-_b0B^=O(VzXD6=JZzn>vd3#>s^ZqW~`unx3Y@hx5Ed-9t?>+ho+dF14 z;++R6P`$6gq};pppGQW4v>uhf!1@TUW6sX?&VN&kx_-843_kx8KylKzp zbBIuF-X#!esAa0>qI-s5b8ch_uZ+@Yu#3QoowE ziEnLF{k&H1mgRK$yj=^~-cHqquzz1qG^9ZFUILSH@AELu?Ope_r2vR`;?~RQv$kGN zU%K^jdecqU)0a;#zo$PDs?9qOB5m`IToq~MJ^sRQ)xTe{N}=U+`MmA#vb~R2N4!HJ z1*-Qvn3Q`TgK=)}%6BXUK)h-9Zvzpk%{vn!ZSyv5WPfYfe?sKU=l$>=+dI(_@eaIe zt~k{@0w(3&SuoD+{TLRq;d!myJM9zHPr~hVqx2=G9dle(z17T9`y$Z&;z0bfx3f_&g zD(PR#s-$n0RY_l^T{V5V^^Nq-f7|LE50N%{i%C}h9?_mJzD9o^KKcFr2$3_N_rZVI z-bD_Gx90=IyE{zEy%S)Z+xsvqq~P7Z<$kee%l+cOmitA&l?OzRm}8>dKel>DL!^z~ zG4-vy+YX&As=c456FKvF?|Q`c4zGxKyFEm_+ry;Xdj^bid#Axd3f^;P9?AK1=8>EQ zGmqrV9g&ms#)X8OVj@)A{X6uL`IK$+mOZbP#P3r5`Nd6eWYg*Ld9Qzhc-KI@9Uddz zjbT#m9R}mv-Wy>d1#jB(`4u8mn|I)o()5=5WBV)M$o$^R{zJS4#JdDipgy0w{A;d^ z+KdRHi+d-sKLZtpl)NWnY#a4XS1r)dAN0+N0lote{fglLg_2WarMnr^67~gHmq^YC)!mA?Qd5{9t z`x;Ejy;}!b4Qt+nTzt<9>+PvM$nX@mQ=QY!&)_X73$*unKXkG2%*R`eE4+=_ zBZ*LL-USe;&ii)KpH_cg@I(JqR{NN*v`P2(dQ~i^%jfM{jqTlb2;vamROC z?Q8L_Qq6L@eBSnsi1#4GI}}o&de4JNx%V*`=k~7bU?~9NO?y5!5TV+AjZ^Lbx)VtcoJAL(zu8i;o=Ov=5tz&N+}4OmFQJGf~jQU2xOWUF^FM3%kx zSt4gX@6*m~Z>OP%w^vQXdmv28y;s3FxAz%XNWnWK_jIcK%h}mh?|6tTd+#Ge&V1en zUD)15*z>t(EyTM!Ov=3zV4U0gFf63tO}l^Fx!CF*4UuK zdjId1PlRgo_IvGBc`tw?^Lxj-vAu)FBmG?nDNwyDyiWJ-3*+40aj=jL-nm4mHg7Mt zSLGcAN9OmQ+JNmHGY0W4fE1|S4`5Q>-`@4j7321fgoSMI-cE#S^Y(1;s=Pzs$o$@; z-Pzva2*f)NQlNTYgGsq}>xQM|Jr)*H^p4TVpV8M6q1wFN++UUVU^p_r_aG0pcS;cA zoe3#Wy-&iV+`E3GQt}Rfg%rGJMKv+5oYKS?KB0+meRvb&jwwxyNkphNZwC)8-cK&O zqQBofsW=1u_YX{)^nR)@9GTy{XJfXv@ngh06;hyj?}tgbx8ob7#_A`9$S5$iS#pV`SFFSy*oEH*Nxx1V^g-b zJLa7XDNwz4!lc~$DU5U9zdJRt6ae{o$$zJPeabEN^{LRy*Ju4uU!P%xzCM$PP;K6Y z5UI}lP$he-&nL>gPYwSYy&lLv-=eAIbopL?H*L=LHijYn9Sw#wWwPjRB``WdG5vp7Gy|bw-aiwt6Q+q&n{- zov)#vNBl42UDcmwJ4@uu=Y9Guws*<|#M`Sa;yn;1<=(4coZI^hETrJwW$}>Q6~%$M z`x^|)y;u;K`^DAwbDiI^)jJ*{)p?KGS=Z{{hc#_vzc2sb3VJ<|fBp!OGoSatx7pq? z^AK;(c8GU(n3Q`bz&N+}VOU7PoA!Ke_qMIx(GaQ5oAi=4(p$@XI*~J<_pT0XZ!r$> zc59D#w}(l&_Y4^4_D+L^6udwFJ1H~x@1#uAe`o!jlzIPNQf4s`s_p(A+QEFvW$(QS zj%+$zKJWGKu)Qx~-VPlR@5V4G_YQ+`Ztsn-kb?KGv)YT&*NIu}#W}Oui&uzHZQggJMHe6j9quf zWNf=TCgZ(FV=_Fij?Ty@LbZAOb=Kk?dGuyGTYaTXieCUn=J$^6%Jxo~gLoH03RLe3 zUFhC@VVv7L4i-}Irrp1DiBN6cUR||#Yq>v5o8&8P(tZ>incsV=H`_aCHsW0XDNwy1 zz@)sty}is83NNPK0Xn_Vj*L-XU;ge(%vbwzu(f#5)gCpn6|}Nx64xpHlK3 z3k%ucy_N{o=Iy3?Ro;W)$o$@e^lWeU`G|KWq(JpP36pZ~`eG@02f#uK-eIdI8pf`g zXb4#~(XfBhL_=1?a6=Lis?FO$&*MGo()P~M_h)HSyYCA}=J)Q|jqPp3yi*|ss`q}F zlzTfGO3AwyETrJQerXr+hoxP_50`ckpRVsBx=idO&LKjzd6z(B*}op^+|67!e(#Pw z*xq6S(%;FD0@ZsbOv=5V!Z`Q+yHj^d0g#`Ulyuo(Y}Ivxv2xc9#s=aBW5w0$jgyE_ zZQg|tS@zy7dRR`E@AY@nciG-TJmMV>DNw!F!KB>#4vceqH}7dF0OC!1J|9VhYV$6D z$g=mY_par1`Mh0y+1~Eh=N+OU1*-QFn3Q{;hjDK2y1gs~K)hGRMr27}(K8~lKG8>H z^(R8LdFMf7>3COc*w^a!YnnFJ{k)2=<#hSH?fbC36Z;Kg|GxWBNP+4-4<_Z_$6%b> zyK-+!0TA!Zi!P${)#0Lxm{Z^)8i-JB-kA_-n|E5|FIK;CXA>--`KhkGh#ZrRh$&vL0~ z^G=0Gb>7XFwcO6?SJQT33jTRUvfpnKIrDj6@5lD`?~Hi+^+mjcVN&kB1;)9(Z@@wd z-n9F-M?YJ=lOa-_H|Zs9m_PRC&k{NFd7t)2ynPUFulEq|fiNleUIpXa-e+JT8@!$U zZS{_a$g=l7LgdWneXu{x7SM3%jGI*~J< z_pX6#@3!wD-fjaB@Afb$_nrac+}>%hkb?K(?5c((*;Nfov#T0DnN`8?N7HnDF%hcm z{vA5de9CIQi_qVf`s23_sz1NB365+!T|V#igV^5N{19)44-oIhFe&#AgK=)}jj)h{ zx3D@^=de0f*LZcTF4A+VE_~15K39lPZQg-{w0VDqdKagaLqG3C-p^OSk@>xs1+cw~ z`Xb&XkOKAj+~q@aW#ryNVVv80IV_~$Jt*=+W8t(9ja?!?H0EFJXWX;j#h6coYV-CB z(B{p4J#E_BRMV^e{MrIIGQW51M{Mu#K8SZAq(JqqFqrP$7sk20<6t2LZ`$*DE)lBD z+v}s!^d|dP+E~x;QE+5_@2P=oZzludT>vRiy&u4&yuZDNm@CHZ9SI95csJSS&|Lnt zoe0(D?HTy0yhGr~{NAI7vAq+!Al`Y90@eE(Ov=4m4=p9{v9OSWcdv_8MfulSB2=5V z+pt&VJs6J6?>#7p?H%rgcxOTiRPU28Dfg~Fyp+5HU?BzXFRF*Ml7A%;q1wD1f?k!k zFC3ZQyXQ!@cTq3II~7u(dhdrxxwqqpQu6Kv3n_Th?%#8WP;K5N5UKX{82-Gb<^J7y zq`7YV-W`M4-u~SX?_@}U>b(;t<=#(WocsRW>0?U)ke`>(yeAQ%+Pn)Pvh2NE1Y1s* z@AY@n(QNM`%sU=Zpn9)^NxAnO80YqGKFU%6jou@PP;K4?5Lx!#^+sDxm(SaEEZch< z_Iw@2^R^$y_I7#~`F zDNw!V!KB>#7>sj!R}QfhK%=*T2-W7D36W**{e;Mw&->vgZ11+c5%0ip=899jBVbbQ zodx6E-j87+#pkvE-P(O(xm2`yr$S`ed*38-=JUQD#`X@^Bi??Yh<7kd%DuP1IJfr= zSV+pUCdn z+t+r_9&oCA_PM<7+3$VXJ==MLt={nvsm^<7><{SgXG&e;gZ_Rt(s+ zw)b%l#M?6*@$L?ja_I*~J<_pZro@5Dxkx7#GdyFEhKbAJqTg&_kI5NNYvT1DZ z)dAW24yKiEfB@A*4X{ zt`JH0?hE7G-f^&y4c@s#s5Wn}s8{731xM!hp86@pPgGXIlIO?$FtWG zq1wFNW@zyq(&i_t&nwM!yeryz{~ioS=Jy^ni|w7*0rAd+6sX=OVN&j0e`YCp2f#uK z-rwyTnR{*7nB3ZR#^*NM5t{o=%~82YM5s1zhgn*@W3RSAf1lnn!@pM71NQvp3rFVn z?m3(7eY`&6oeC*Xz4ybU+}kmxl)QVvLJHor=kqy4s5b8sh*bA_4D*vVwf)|Cwz+Qn z-W}&6-kykeGNeHD-U*X(@24=%egEz>$5H^~=OwMH`DBf&=96`-norhm4nA4;oP4q- z5uw_=3n5aScT8*7-K6KApKY?*A98<18aa<$A1&ruPM7cXchmW7@9=jJ?|4Xo>b(vo z<=%H-oZGwkJWBx(@Av>uF(trL+!x>}HW=(FuKCDQ97%*~^Dcl$b>5My`&#|}j+Omy zTkSV{`=aW<4_t4)<#hSHT|Z-cJ9R?5qag*V_Y#YWUcW$%5K$eGXk^g_0`QwyZOy%G@bfiNleUIpXa z-e+JT1@G+R3k_$VEi^Rlv&azXnrOH(cCo>Ep{?HW5UI{PXvQe3_gCVa%UiwPj(hyj zY9IUle}u@H&--8^;{7(_?YRi??hcc3?*tg<_C5>?DR|F!oh@D-He1|udba4{I#*mg zC{DCXwADKrBGq{t8}0NV@6VCf`|8O3u%`yA>jCplCvxWV-j&4m_OFR}yM2jxw}(l& z_Y4^4_D+L^6ueKy?=Uv`ZimruY=^OX$DPLcr+zXP6QSDf-=Rt7Q@lYHOm=ig3_ zaeGPcu@@(2llz$WCOER`bosp3FJXJP#eN>@uo&@f43l#2Fc|0d-UtgRc+;NGuMnZy zyaShL@y7h5O|AC|I5NNYvSn=Va2KS%OCSa6^SR4Xb7kb-Lt&iTdpRtm;2ja+>61Iz z)93Tao<0kvdiuo9@bt+iLbZAOEz{!tUWGub*WYsg?~m73{eH^=I5NL?>~gkukvrmD z2q{p#D||)w?hE7G-f^&yg7-g5-NeDm+{CD5ZsOG?ZeoKZH!+t8)#mNBT#NU-$&akw zPm_C}OrN9r_pe34k@>x+u4H>}!=BFzAO))T1DKTexAzKj#kjpAVIc)?|6RFzD%Ux< z=S;Ihdm61y+w<+-WqY<0q1wDXS8DMt>RS#!1?cEmp`B)yL zK=r-`lXCCYUzd{iSXfBGn|A+RON46kc1zacE$?TZ{lRc#e(yo6+1}ypkniW2kOI~F zBuvV^>#r&$?*LfH2Ja*yRGYWM>R09M3rFVn?wP{&cB+kdr$P!;@BJ_-_jX)UO5VL- zAsf8s5TV+oJ~wmNx16y>p7WZv5UI*Rs76TOr=bkOI|vCrrw{pTaoz{kzjQ zmI5F@F9~ik#9;T&aKkqb(vo<=%H-oZGwkx0V7R-s{G?izWXw6}!}GA)c;TU93}o zw{9d6s?ECqBGq{xc~%a6|Ljn}m#TmNTD^6a)8+GaUC;LR$Nv6UG^9ZFUILSH@AELu z?OpdfO92q?=0B}8COl3yKHsv+Sm&3;#)rqJ8v7HW+Pw21Qk{2j|Ly4eXItmRp#4wY z52~!UoGzcY{YJL;HthZ#3Mo*%=fR}h`xuOKdsp6IDFEV4dpVgLQ@tZ#Qtq7v)_g%rGdeAHZ&e|c=S)jJs? z%ijAeku#t7=`C#UOV>xR|2+$@RK$BAOv=4i!8o_~8CXccyWhEro8@25TWs}?hsd(` zK0@To=Y4Q1;$47vd;WlUcZW&2cLI!admn~{6ufEoZ@aCwdPhTK*?XrGIrDk%`jPD| z{E2wGZ9}}KblXu?7cU^kxi$|=e>Rh+dJqk;_a{< z@oo&0a_=x0=l0$R3)$d(g$UK=9k}CFd9Q#Y^LsD*iS2E?fq0id3e@Lwm!0Oy$i0Wc zIJft5SV+xvcWr- z2-W88wfj|hN5PT#y{D$Ly^U89?*d4H>iqyF<^AoQX08~wcO)!igZFkKRGYVF`m6E| zfg|&KkIrCw3%3yOJV=4+eGMk%-mUkPlJ{6xNYVR$fB)KAB2=5VTgI#M9t=n3_a2nR z_7*QA-kFdB)%zq&%DwAnmXdb>ETrHaJS#|7by<*Z=TAX8zfD29)X71*BqCIsw?mc| z@57t>pud0Vt*@t{zpu-*N$ zPN8`6UZHrqxKLbHTqwSEuTY#rglh9Hfk<_)$KKvo7xkWXV7%(juXWBg*Nxx1V-DLp z<_zMU3@K2(cfzFH`zeff5Cox8pHWc*L&8Rdn*NY!Yc2@F#+mzunEv1YY3y#(e;xop=B5`dfK^lztukJez5g`dQkf{T4Zv)8%{p-E<$~U5I$cLkd*ybucOSz60aj z-pz9@1wg!M@2`y{LbZ7pK%_cv%um`RPibTA*V|_~T|RHu18i>*d;dHdQlNS-fl0ad zc^K#RuDjn-0FB=LiBN6cc@SCl-c=4*PM6Qy{t(;S{VdYop^yUAdmc>6y^p~-w|C`( zmI7$>HV~oOyfY!P?7g25IrDixJk0hEI)``%9x_*)>Ky@-a_=k{=k|UK3n@IWE&3$c zFg`uip!3~l*d3f{7;|Bzq1|E2rJ~I{6(ZGn56s4Y|JwJ7U#b55+D#&7KJV*C+1@FC zAl`mQ5bt1^lzVT1ac=J$u#kfH{&6#m<2H;ko=>k}JlifI+vnM2Z;zw4dM87qI`8d$ zu2_9useb+12J-&gshnW7Z`#Ota{nxmGoSbAJhu0xy@M|61XVN~*n&5IOUCAN+;w zE!;!AJ&z&Y-C}{rjV)P4eFaM>d@+go44OdE#4zOC~x)q)()2pwc5Wl@D0`Pw=IAp^LxjhW_yeK z5br`rf$Cl16y3WojB|U(!9oh&wEK515vtAG>$DbctY4)~>R)MN?MK0p`Msx}VS5X? zh<5>`K=pnAlk)!d{@q+LZtqA~$OiB2M5s1z&oi&eI|Po*?>+h)+dJkr#5)gCpn6|} zNx66Hv!&!c78bI>do2;F&D-tVtMVQUN9Ok)RKWHYvJme~NP+5o5+>!|_5Ua(?*Ldx z!F%w;m4^JRm4^Sid~NuoPO@Rus5OQpB2=5VLxC3WistN3wSXIQtoHk?>TPvBVBVcCnCr&x-SHCJI|b|SWJrPP zy%Q$o-cMni`~KbOqNM=H&r4kQr5T@GNHf|yq#IoaryHM**<+kUglh9Hgh+MXLT+WN z-?tX@FxYBebbAB+`=g|Pi%XW%<$L|z^a|TM<|m}T;~@pA_d1xAd*6X^Ztv!oEd@Zl zY0u{)iBN6c1rVvy8~Oe$ZLII#(k9KBB2=4q9z?41p4)#r`u^FHf>71(w^X@i zIbA+)`|E7)OUID@4uuq`-t%Bm?tKi#xxFj@X(<5Wedw06*x|ObIQX`+`1MU^@yvB+ z(LjW1^Uj1wb>1`XRYpDAH~-A)^G>Es>St+__MZ?r^Lan~i|rlr3*sGk-CS|1cLYqz zy|ZAP+xsyrr0~4YWUc>byxW zX_NX@+SKl!C35ETK7E_*9kUca-@Aihm><)&wh(-p#)pzv8M5wm=cj!IyDXa7LkIO>e zKl{r*RQ2cAHo=iir_1NP{yy8=xC`-iC_=m&!=&6h492;=H^M>+-rx56P3IhXLAU4e zW!(7alhWMo)aMoL&%WJ*#{rd&b=S-3=4m}X{Jcq28#!mg-GV%GCS>1c?A7XFYr^NByfD%l-Paw!2-%%%>E2iu{4+B|v@9$Cf zF8|oTq{?}R{?Sq1iI`d4d-^G{xAqO;U564(y$>SDdxy2OllKe^Wa0h8noBkQv6@Mh z^A0@KQQi|Vv%2^Azr@~-9fWroN-*`_jUeyc`_Fdro`8WYyswBT;a!LlOuefSTOudT{IH^@W@rrv81(-Gvox1(R#yNi#$0FvHzCRNV6 z44K~dKE>3m=6%vv>}}gfcqg3gTyazHISBIJ<>*)TZoxp7ujglOgM9U;ikx>LGQID8 zn5kLK`%o9Lcc0yacltAPet*FALPVycVdfe=AVCDmPH;wlq-dey*q9naFg{ z`;y`*fu#4nZ*?{NeQ?_*djGwNsaegt-thFqX#0YR(Z`Y}Mn5}yV)QX4Rqp(qbiQ+!-Se*M z)5-AtHNH*xx;B@80cLL7T{Z7~f3dg!V#3?+0>Zm5g1mP!`jx%cVIV7Slk@j}CRNTm z!C%H(#?!UAd|jKXy%IC4duMkSdmnv+@NPv3rq|~^E_AL8?>!0q%HBB`$OG?POsbrB zeD{v>UV@p`y%+ZodoO#N@NPy4rrtgmnR|~$zp{4*2J*nWib<98j_lD<-t#fDy7$}w zv3K}t!n*+_n0lW;kUzeoE_SY%viCd;Wa0hlV{7e?um87w!1y}*lRti9U%F_meFKv! z=N%d#1bjPqFt-%DWCFn0g;XkoOL|q@BEHU?2uX88TBx(TBV?Y7NzzIJV{ z_C(CA?mhlevG=mqh~v8qC762eMv(XJ-K(9vCtx58@9YD~RUxlEUbXnfxm7=(exhp1 z{ZCe9F{yIiewWI4U$f_w+uuiYZ7yHe=4y|^%RpT=?|mBm z%IEK)z4ZkkJ}-G;LI0?v1^uI97xa%RPVFBx{>lDPDNL%IcQZ2G^Y-1lq=fbDo)&7j zzw$}zb>!cVvd@>0%k|w=d;i_9kJx)>I^ms(5=_0cd@^o#Y_9>=jHSd#Gi@kTgN_Z#qb*{Ln z_Z$Ry?{f4jd$(X953bh+U9CS=3#3ROwDTEhprKOuU|oU$M++=ryoJgpcdw~$+y7en zwteI0Z`+eruC{+0mv8SL;;DBgGTrlb*hU(DZ|mr$KMn1y_k7*H-?ELVSe^hMu1(ZliJ8^Cvj>X3k7g6ztti3t`n*TDb7gq%N$6Mh&cQ$y-uHaaKdSKk{!w4Q z*FP$=q<_>!U-ysN#iYu4#}Ab8eqg~^!~5;FjrF`Y@p8BCw=BWT>fVd57kkfof$(ld z38vmYgUr20qhHxO0|Qxjf3b2$%!6<2h-rFbN6dpOcEo&>u_LC6NtN@Cyk5rp$}Xv- z=c>QXcl-N_^D(o!_uL!A-s@i^yc3jCaMw|B(03{&S*Y7<;_)$3NRn#LVj6({B`eAI&4Y z>rjHJ_dx`C@30~5uYCR< z8mTV;@p(zY*GugeM=rBp<@1WY`qX0kSw1c<-y$B)a|m zwU8)%ch%m1_lpsGk9mdg&O`~O-fIx#y^o+@**iE|UjV}UuU-qa)H|Qm$}`ioUk)T{ zB_W~OR3=r<@AYpH-l-_T)O$ICy!Srz zD|`3U^aUWiNBeGcJU6P?G3?EHACDw|e{Ec2U-I~8 zUk|#*>btAv?K@oTy=*DrorDrhz0(ooy|<%Z*}IEfUjV|}?E2i!q{?}hA=5o?*2}fI zuD4yAyX{j<&1&8!M~J<5t|Gh>hC5f>)O!wsymvYJmAzXqkj3>{P5H5Y{A17v{i!17 zU5HHYdmmGJz}pD# z!3gr+3(&9ZU5bG`@IJ<*%ALQH;+?zfeeVLy+_t-F-ubtSy~95uy!}QK-hC0|y_3HdEmXDNtN?XxV@viS7K&$@9Z&R@12x)D@riEKJRgdb7gq%N$6Mh&cQ&I-e+#R zm{d9M_%R*jy#zC>doLa<_6{#0j_+oaVCwC2r@8lN^ecO3U?2~?tC&b)C5 z-n;ib?c_ZH16g>_Sn+iU|Hxue<-GkSbd>if%&hJ`@?Np`vdx5dAxbdyu11je?l!TV zyyGyCg}2S-AIm=$F{yIit;qEL`>}|7o$IFVJtRTweRLDyor@Aoy^9g#y-%ZG`TRZf zK79d*&r62Xj4a_FDNL%IcQZ1*?;Vn$@2=YW?|%1-z1No#-kB)D)O!try!R3GD|-h| z(ied6HoLzzl}VNJZa}8@y?foS@2;A6z!b5!Kjoc@5=_09BglL2L%*_j&&m1%NP3TD zQsunskm-Hzu2b~gRrB_pD)v75A#r>sp#)R!bOd?t?dVtb?(%@X0FvHzCRNV644K~d zKE>3m=6&)(vG=SEgm=PJ=Zc$p&q0v)E=RwzcMArxxL)g5{87w5SM80t{$xYUgEP0q z{C548m_ZNfPZc@uLS(wd zZ7)-^n)jZE#oo)-6W)>23GZ&m4a%Dus=Gh-y zU)KF$PrWmd>7MuF!}1J&58Sq~$MctQU%37Eq1%|6)x2vG#ojxq`{$uE2=5UH^4?3) zuk2lmfh@euuFpFsdg`5uO!vHbUzPSIre-zol1Ihfjhh}Ie*gRt!h0}+y!Qh1D|?q> zAPaB)-dbDx7?Ub@{!V(-xy#=7F2KxfyQ}7%pDgzFf1P+e_e&zY`y$ADC!=54dmRR{ z@V42O#qy8+OsbrBLUKoWuf)vi-q|z7-c!COj_+2KV0wMt<1y#T@ZOWquk4+Jfh@fF zduwg&T}-N+cl^wb@?L_O)x8%#PI&J~7Qdc1qXbiLpIPSKqtUPIoq>TYyv@$vRZOa! zcjV(8AZFsX9hp|d;6I}tOh zdryBt>^_e@4zQI%6lSaR`(wNFR{1nbHcj} zC762eMv(XJJ-3~_Ctx58?;c;>pp_;(pp9MskT&hJJG9cPG%brsmGk!dmyGu>A61d} z*J5}0xqZK76lPZU9ywp^o%b!_U5FA)y{i%Ay}Qk8C+|26Wa0fE+uO0f_pFZ1od0QT z{k0{ru}>GoE@D#Uyjzj!-utm7e_lfVp58|dQ>xheFVy?kB}7+t%5* z$5M=Rdl&GJfXPV@#^t`8(+a=PtYFeaSiB7=EAWwd^&9cH-bd zx4+*~fSKENSIs*=Q|z6#o$&U1k?`(|An%=wer4}<7|6nV=)OUfZ#}uZGSjEJ@}vHZ zl`Vq~RPJX|<-8LzWxRv--eUMYy`Z1F8QRn4baDIs+DgoP8_$Wl&;P-w#-*=Dot^bs)Gj7f&O81k8SgTmD-8er ziq~(s*w9|Oc`*6?wzkc6KV}JLR`*`KOzfRUeO}Ux5=^~)UN-k0jeceC3=Cx9ZFYaH zib<98j$9_=&3d^um!E5Mw>=*-t9#GQBD~9p*YgIHVCsDWLH_uTdd0b7%HH!ZkcD@` ztq(i+#|9=<&O0=#qr4L_v%2^6+iUIQ9fyG|yv@$vifS?M7kl@~C%kh}f~j{gg1q->^edmghpyBYfc(7V%=@V+OsbrBGcvvJ z9rC)qyK3*h`{jzg8`lutnJB^3dkuoT_Yw3fdk4RvFMy=?R3=r0SNDmJ8q6$T~e#98NRuq<c0<=e^*I+YR?u`o4Lep}pgRKtr2){qOpwzPoDPzIkHrDTRc05=t=jPDhaU-j04{ z?=ElY3qW{Z`AJm8si7}cEF4l^p?!Xq4eblY zrWo3k_bH}kHSd#ei@o#K5#9-T&J{QHo`WFoU553 z^8V47^CPQc2EDC6Rph)2k?Ec{?-z4?v%&X`nl}t>{@=6h!%WR;-iO{1d-tg(yyI6B z-qR4|y^GMV?A?TcEWFLG&x79a)H@fMo_Vu=u1$13?%G`Oy-dw&-h0-Hy|oVr@5nWT z_c#Q3?^Wnm_O8c3*51K3TiZhmw%KgKHd~+I?rS~u&P1m7y|*znt9jSFEB1E0Pk4vs z6W${bJ@rmSruV%!F*U1smlTM-8w&{Uz;%T8U<7&Z z1?X4yF2z6=-Zq<7;C!@wkIhkFv-NrJ7?Ub@{!S`z?y~p23ovur?y7m`zc2RIsQ2G~ z?-Aa85#+s-(XZ^i4g*fYH!VsFRW#PQvV5=^hpdlWiX zhWDO?er4|*4CI0LE+$pZJHDu+yq92Rb??O=ioN@6CcK+bf~mL92j1c?M`G_O9}(USD8bbG1cLnW9kt%MV#?n0Fp!0J(Z*o=PtiMK zj|_V%_M*BGvFoZHj@`hd%6W%=B;)->W{u(g*;@hehIZTLdcWn`MD0Y(tnNL1qu4v` zL&CcbC7602M3DCm+t5zlGcb^ax9{P~%GjH;EBi*=QCV|&NafG1k(H~NR5|a!jWXW% z-VrjK_3Qk|N%HSSDgTL>S>1d5zs24fb$woj5=^~!BglLAE^a692^h%2yZhPK*!ym~ z+rEFyBlfE0$@WFpOt)t-sdCW_9n8AB(+hHN^2mKg+q&YWgXJkqs+@N-GTrn3ae6TM{qoxu zbTfQkm3lo7*`)8T+WYT*Tg2YB4TN_lN-*_agCOsH1pUh1!JG93AiT4$I1t-A>_F_U zI}gO3%sCLd|IY)lQ<+pb?*?SL=iTx^nc@4!aW~#-@ICPKn}#;!-D``!yK3G6 zv-7u|NtN?1L#BJ)l%H#3uivSEe~PJD&HJQ7>}{jIpPEqNTyazHISBIJ<>*)TZoxnv zT(1ps=uZ_n??PmH-}^9AvzqszDzSGT>V9f`CE+~{LEgIv{mR}=7{~+fpej$jbCKzN z@4ZaTYTkRQ#okj&h}ZMT{}A5e5ahjAp zvDog_o_c2@(>?Espc=#bZ~pcAP~CX9@3(DZYF6{EsS$gpp& z76Vy$-+lbz%4_y!RX(`n=gNIieXCk;*Qz?#cA4v+V-R+_t-F-ua)2z5D!|IKKV1 z5#D_fRU7zn~Qsul8K2z~#{al;7*XJuSv$}V7o!C2%x}VyL5=^hp zdwlL(8Qyym`jx$NFp!n^OXm-;)#qPl3xDZDn|lt@Ax_y@4P$mKVm(@ zw?u4U+j+AuG_?oP4ytg!pVzjxn&5=^~MAjluz zQ9GO~rtCcr16g?6!Y>_QTmMFw&2}`@HsjcJw(67t8<PcN_-tzKnuR>p4S=_uFd2R~h2e^C6^O-(9u$-~GN7dmsIfIKDGcf~of!1bOcx=vVd* z-m5PF;T`*Wx5}GtKfm&>$M11`S2S4*iFr|*%B0G9Hz3nJZ{F|XJrM@q+xx%n_V=55 zeXH-Tns-2h*xP?2;hl;SOud&Q$b0WYzp{7F@AL&Ayi;x(6I;Cbo!GN){WNx@|Ie}i zyy{~g%cRPA*CEqA?|)_wGWb5;c$T64uqiF9(w#jF z_fyv=Tw`cc-rJa()x2wd6nh`tP8{E%2MO;H2=d-b(XZ@Xi-9b>&CcJQfArKl6`AgN zQ+}?^@On?YzHee`R`V|TN$frAbHY3D5aB%-LEd`-`jx#)F^~t|$Cy;P^LNru&RzDt zcL8Q@+g&y9{KI1J@XrWuzb3-FFM_;xGWwOh*I^(Jy!SJya^4AtJIZ?{W>)vk{zdG) z>B=jqL=U^ZU?@?bpXz%Jj(|+gJ=j_#m+4lZ_KsdC=& zzsPu>|H_4i_uILzCK}oa;f+5V+SKu#h?&*Br~fAQ4&Om|*P#Sc?}G^P-eE`E z$$JI{vhX&$K3~nG%6SL=CgV-{xihoPm|5L>{Bg1Om`#Lt8A>qq-i;vd-TPQO zc~8JV7T&$yxTTzbWHG67-hRiWynWvO(BN5ew(dB%-;Yf{*Kofjt;}w0m-IKZDes8i zo$IFVJ>(Cu_n2bBI~OIGdKV+ed!I(X^7(t{Nqqr`&r7EK@c09-@EHy`tGWE`<@ni@1(BJlTd=GcRGT+_jdFv zdv|Ho7eLb6&ZNqDmm$;p-lv$F)x1ysE%u(ZjyS#(PCHlJ)O!wsymvYJmAzXqkj3@d z!8H%rpY%_*N81-k}(W;O3aHecIWHk<8oo6UB9>|=?^56nrN`PlF$QszDszw;BqJN_TSdm4hgcM?>(Kx-r-va@5oNhWivg#$05jjuR_1FcRdEO@V8vhX&$KJV<~sdp+e-SejWTpN4*Q~!PwQ?r_PiLcmu{ilR? z;Ms)tU<7&Z1?X4yF2z6=-Wfk$Th2d@F{yH|=SjZKU3Syk|4!rmwYeq6_Q~&zZQ}h{ z0cLL7T{Z9gE@JOx6@<6nIfQp#1bOdd^ecO>!$20^U(DVS!$0;jsdC;4U1Yp#Ums<- zpE9A>Dnond)9)DCl=n)^tnQtCuGo7gb^dNe38v@o9$lR)!+TFczp{4@2D0$Bt^a3$ z?a;a5wu^$pZRgz?Zu>Abd>4}{=N*5pjJLKgz~DLMxn~XSv^8%U+LZSa%&hLc*iY=e zzLYq=n^A(Px6gUz-lNg4?45yuth`PBKD3HSmGh4DlkukfT${V+@A;Tn-Fxo&V((eU z3GW7!VCsDWLH_uT>gHTAW$$?y$OG>UOsbrB==mMxorsy$y{G$&z1Qy{yz5YcsrNwy zdGD|b+R1wc2J*mrHIpjm9q8Xt-V-siy7&0*V((dB6W(Pg!PI*JatUZfKmGk!NF5~_5UvC)huU+5yZ$o?fh;D}aZPe@k zD9o(xJ+g<``{*IUyAUOqdRHUJdw092oxI~PkcId3zeZKmzk6Rr^>xoxO!m#MNH}j> z#UdtE&bt+v?!6!TXXfLE`)dQrcNyBlp8DI+ro1D1IM+?xdq{xT+n;(p&qWEQ-o*&= z-lx&8eEuGKvAzJr=Ow!a_tX01g=(*z7pV>U=yt8;rO8?flPc%kj7;~uYd(9&aR2PA zw0{ik!qBtb{{C7>fWEtG@4x%?6npQazJH#H5=_0+@bc_1#tT4!Bh8J?0zY^*j|Nn0hZqkoVq)er4~Tz4QejydUp5 zcpd*3%cRPA*CEsU-d!)%cUR5ZH&E>De}eE%LJ6kc=?L=P+tIJ=-Q_ZU0SNDJH#Eoa z4?B}8=Us+O?|YwOYF6_;*<0+rte)^r2z0KvsrMWNdGB)cD|@$KAdBm@3kvS(&p!tB z)}JbJ-i65YzV~6KW;O3aSBSmWQ^$Aw<%IV%1bOcw^ecNeVIT`{v-5Y*6`p$MBGdcc zdzqTmy!Tuw_8!wf9N&?B2=8$S^4_b^uk2lqfjsc;ex;}0naK3M_co?xHSe0M#NIpi z65gRfg!c#pdGDp@SN5*OKpuE^zRFYYRAhSJdlOT$ns>?7V(&4(6W)P+3GcxO^4<&3 zuk2llfh@hx+>SA+a_8@)tDU>-eeVLy+_t-F-uc&vz5Tx=y#4wS-hC0|y_3H zdEmXDNtN?XxTd4LS7K&$@9Yq<_p*J2cPmOTy*}>|>|7b%dlLGUy>l>-2j07wR5|bX zkdE?Rf|=F57hfy(Uf)P~H=_hoZ=e3=-lNg4?45yuEWOiW_-phkCRNTm^4gB_o{yQ; zz2}CBy=Q$(csHN~Q|}W9^2c{nsB^`Xz2{*d3-7fd4^;4v4NR(>cW9WDckjoIzqjVQ z%-C)XHnxfHuO(t;b?@l|#NO+FB)scTf~ogG1bOeU>)OeC1_rY5uKjPb#y?gwsdCtuOsbrB12Vnu-Rnkuch$TDBE;T14-np|D8bZwIfA_RKJ+Vl_Z+G(0O395 zyLfxWB@^s-ubpi_e8r3QNAG&WK9)(9^R7dtd*1gvVf_8IxB%ntudTWHDYw7B)-^)k zT{UmtVPfy2)bX8!5=_0*5#+tMqhHy(%T4+M5Z>oRrD|t~J*^%1WuCU_oJrd1qoJCe zNtN?1L#BJ){PowVlxD;C)h_+lOK$&t=qaXVHSd#=V((dpiQ_wAm~+KVz2_jvdzYhM z*}DY;SzNE>-Cth$)i0YW*Yy9WGPp;6<+HctRt}2PpDJ?Rg~)WzyZXG34c||D=F1+2 z@2AdQ5@=}i&kweJn5kLK`%tvldkppc)c7dEdm4hgcMbuFx$u!P{?T3Y z)H@TIZhHS&YyA7qAFnk2-rBdJ#x`+(Z5vawns<#|?0xhX!aFpU@E(C6@4XcL%HFjY z$illY@jQ)xbhdlyor+91y|>?Eyk8m|XKWL`uFZ9PZ(?dz^DY@7_V)iD;T<@f@E(jH z@4W#1%HE|I$in;Rin9jVmUJCx8`N`PT5kV=Y0nNDc#KJvJAWsQaPG2u-t)3vH{4&- zy0;kGd5`%ons@$4vGfYILV((eM65g#S!SwpP$1Tp4;k_rJU)ehc19{-Ri%FI9 zj*sgo?Ne+!DSOYuKo;JYKD^SNK6jP<$Aow7ONutypZRO6eFKv! z=N%d^#LVj6({C4huRle2*P#Sc?}G^P z-eIHL$$JI{vhbdL>vYGyHM1NmdOYWN=h799rXBA%Rx_z`-hsEvcwhIdui^gL3;XUd zwEven-O#4ICt_xG@9|^A-edkGyvtC6srPOKdGFqLw3GJ)3}oT`_A{?&pRLZ)?5mb* zfs0pYckWrPWihF8-hN|byvycqj&U8IZQIaWiVSVa*R{FwM`31l?~!B0-r-GzcOgnJ z^{z&c_wIIQJ9)=pAPaA^>+?lSs+@N#GTnPWCgbVaT)wW&)s7hJTsL*^A>+i}vswu6 zT$EtyU5p^_eH#7B=kK9+=?g%7UZRz!mGh4jCRNV68JTW+r%g28U$d7R+sh9a+r;@h zWSqXcYVW`MjTd{5$tJurQG%)W8U%UoBj{K54!&Do0K$9r?(Q1@n98Kec{d=_J?|N} zKW4bU;{U-WL%Yvc4nv#r?loTDT{Z8331aW?cM0!Qlwj(;96{cDANrNOd)}ij0O4(` zsu*B9wtIl>OW$x?^nh?%+P&dpnN&INI%K-%ZS(1F@SO5nnxWmNDc8`Zyt_`&cUR5Z z_g=BL|6;;B2_=|%rz6OFZ%4nfcbAF!0#M#2-#@oAsdCsCXet=xYxPjrrvW94>L8Zc^{f2 z_MWwp@QzO)yr&_^dl#W!*}Dk?dEgy1$y4uKWP0CwFH^Ic_nygw_j1BJ@_xd59D=;} zD)cLR*JB_HZ{N^Eu|Iu&EcU&>yV!I01=@W&h1FB0CNQwZ-72=d-b(XZ@Xi-9b>^Os#z@%xUeDz3cs zj*5`{#TDOt@oq)u2R!voMW%b+OaGW`_`ce8+deV03v!Pd+LZSure-zok_W}!J6|Ha z1E&(+gAwGt7ocC+yA%UicrV*|fp+XvfHo{NSo`2uq;~0BcWB3$RJrqa(u2-jcF%j^ zhb4yJTdSCMzTx|9)xTb3Xj9$=n7M6t)x7f`5_^YJpO5)XBfR?}$a^QFU)g&d2D0!r zyFTB~q{?|GJS5{y`MEaH>$huj#aCixb?@wl#oo(aBaZJ@lwf*&-ebCRWq9vN=vVg6 z!9W(?(WjEu@sC|hs+@QH!yVNk_h|GhduL!E3-4Es zU#jtsDkfFVJ2J7Oyys(Pb?>>465ct)@!fzDOubJa$RFQPk2qIM*?S%avhW@=>CXQA zV*`^a=NDBmefw(Gcb^ax7qo7HIpjm9hlrv z-V-siy7%~*V((>33GXtLVCuaaLEgLfW9{TU0Rws9oyDZedHc=mDDP32S>1c&<6`ew zFB9H{D8bab8bRK>+pKo-j>AA6crRj7<-A*w>E8RXw#{{Y?b~$Zr^lV z3rh9WI~SSmd9UAIY4Gefsb@LsdF|3m4Q?>$e8z5U-Jj_=3?g!ecE zdGA%|SN5*QKo;I(yL8<;`LeECA5H1H_2+@-Zk;*kysh1z_S8EQneKTH`(Mo#msi^s z^2#EEe|D!`hIZS={(H8)jj379yCzNSeRM719lDV49)Te5y%hb*-nAIW!rScrTIV!R zy;G6to;T~|+C-kNO%&h6)U4)RvPkT`GoA1be1`BIj3Dp50R76|r5MNq?_*4=-1$3c zk#m>5?_GeI+jdvYJ3n3QJ?lBb+wWPzyDx&gcQX2wz1LwN54`s?sdC;4=^f?05;LoN zXD=3e`%~X%YDEdA*XKQ+bFK{UJqi8F-Z>b^!uy$TqU|4@f2)1f(ueHP=cL)uJoFVoe^9pf%H=_hoZ=dJQ zy+@;8**gORS$O~OV6Jx6j#XN>nQv$+kXY&-GCBIy-y&>AKy_+oGYg6Jr4s}c>fx>t+H2Bb>)-^n=3p{qVp8S2TaoGJ`?2K*48OOQ z_TLMQe;-)&l_5@fM=W!$o4WUqEV1`a>hJw?QG%&=F@n7JY4j_fzlXk}F97j*iT@Wn z!qeiv3%7M@3GXxg{DD2+yJBDplPc%kj7;~ueJZjIzW#6hZfO6x+TQd_Sn0l{4koP`!T zyv@$vQ<+pb?*?SL=S>~2u1$2lc5SYBujTsgs(A-wi@j&PK)jx(q6Aa#p0vzqswRfPAmgm+{v;XMvP-g_1LmA&gR zkcIc4#Ti=2$``a3n_trWzs%CkI<#EtzRFYYOk}#}J^Ak#!{3JnEuCv<`$t}HXj9(X zn3~nRYu*xjJDwuEL*FF4M*)!3gr+3(&9ZU5bG$ygOfc%~t+#j7gO{e+oiy-fvjDBVBbr{IPd*-}AjeqQCQsul8 z-jVTc**4X1e`V(79~jy>OV%6OZJX%$UWu92y|dR6-t&p$yA>svUZ3|^<6IfudlLGU zy>l>-g}1GNtN@CUn}En8y{lu)PBe^v>P8V`cvLZ zFtfV%;&;W~Q&I`1o=T%IqoOk5AQr^Vz>e@udvukt3 z=VNAd@3{qp_rD1529#jxeF8!L_>NlVTrp+uc^Jq8?+r|mGL&HIy&FN^ zyLVwbc~8JV7T(!6``TaL?`JO#>1|K=&p`Xp2{+rbm{d7$zakm$#t+^%e1E0WZRZ-k zuXg1}0fu(l=6d~hZLanx%&hJ`@uGV@^2-Q}^L}_=8xKsPGY^s*R zq{?|WBhx+aD?*D6_s{k{ajxO}Y;UjdGqkDWJLDsMch%m1_uDA;cFZNbGf{%6_ZkFw z?<43}_72{lF96|fc6~mTNtN?%K&E@%l%H#Jy@rt9c*VEcWiRobZm{M0ig_koPV^ zzp{4|2D0!rJAVgl_S8EUncnx_%hasqy{Am^BhJ8}!*Jq|(MdlmYXz3VZM2j1Pw zJoU~*ruV(KF*U1s*K8%cml58f<%IVL1bOeJ=vVfx#Xuf-ci!r$cPcWy@4bnsSSA+a_8?PhjW*`?_GeI+jdvYJHJZoJ>?m~ z+pm)F?u#Jros52E?{yf+1MmGzs+@O1RY!TR#LVj6+0|li+XBM76(yKnpZEBWb7gq% zN$6Mh&cQ$)c<*9T<-FsoJIZ?rW>)uJTtj%zCcK+bf~mL9C+6Ox(XZ^Cfq^W&&;0$h zDkfFVJF=#uyys(Pb?>>gVsFRegm(iW$$?y$ilng{;M_qv4KgI z^A4?*@z(yh#qfQWv=7q_ZCgUDu}yqFmWY|vy{CUB_Rf2S@UBA%rrrk;)te z`32!k-Crw238voF2=dRpT=?|mBm%IEK)JM;x0J})uzPGM5zyql5feeaN+`tGW||L(U-?Cn@doWC=WsoJce%d}@# z6l?qZcW8mfc4&4cRnEH%neKVt^3`XC?<=i*{})3$e#+&B?>kZ6rgn=x) z&92vi_Im1_i%j>tDL>aH`o5ZLbH(>EHLH2=`A+QJ=S|}Hj{KJJ9)}?By$b!x-t`#B z!aMlGk&*nP`*)stXCl*0@7V2zzXwhG`6}b@t?dmnwu$>|+nAcwyleJ}z4NXjyh9rZ z?-2;{-b>N1>|Kk2EWFn}HCW>xo%ea_or+91z2EnD`}fsco9lRXZLanvre-zolJCXd zjuC`+;C~74!3gr+3(&9ZU5bG$yq8_#KQJRSU|?F$s|U6e-#BpDJ8=V#F{yIr@1*aY zyX>BKm*-a*?x)5r{L9cz9p(P-uN7eCw%t|p&i_H|-FOS(?bk?n_eGHRPDa17_c{z@ z;ca&Q-p{1Uc_;iJB&m{d9M$R9h( zdp>4X_n!Nc*juAs&l^yJsrLy4`Qtn4kaNY9z2{*d3-8#+SJ{*2y=_m6d*6Qh{EzL= zzg=bDz@*A~hyEnv{ZZ}?!~5$T->VJx(~2(}U}#gX|B0Ac-Fy0Bv9}|Jcs;K}38vl$ z5#+tYn%c>G1_rY54u5TyG@U^eTu-9kdw@fv(DPPy-${&T9)xAd^5qoR7gm)oI zF!ioRkoWG^+)mzc7|6og?D~8WlPc%kicI(3kI8ttHkYq!bG0LmIM+?xd&vL9-i_B2 z-nl5j)Vml#-upEAmCxTpf7KU&_`GEMn1xaNBZWzo^KM3_o8C3ahWl%_?mLX_k-r<; z#QV39|LMD{_WrxyZ({E$*AU*BD8bZw4T8M)5%ep22OrfJfbdTHx`)O;rZTB=-VMlf z&wEzD%U5=V#X@ zYM)|iR`Wi2QtaJ0lsLWr_5O&G`n@1Pb>y>pT2eebMtk=^J@w8+rhDFHDeoHYuT8q+ z9K-#z+IxB!+HITY^?Vysvzm8JtJu5GwS;%*UxfDv1bOeJ=vVfx#XuI`pPYAfMMCP3 ziin@5RZP15)r#kPl~iDcBc=tt+_fAH?viCX+WZ`XgeZHSbmGe%ponz}{v$^R_`MEaH>$huj z#aCixb?@xXV(-Sjgm)`SFugwS(aE_oy!RyZD|_c)APeuI_r+bqKXx&xa^CTsJIZ?r zW>)uJ>?8JeQ0MPvlwj)ZbC$XHX!I+4XJ8-;@5DdO)%ZshlPc#O>C;i(^D(o!_gr7G zciPp&@!fzDOubJa$RFQPXFFF+*?S%avhaTHfyit5#|9=<&O6k%qr4L_v%2^6E@E%n zjf8g{N-*_4h#>DBc1}Ba&%i(y-e%|T)l90KcVL%}@}7v9)xF1`EA~!{CcMi~f~ogz z1bOe?UE9ff0tWKHJBvw`^Y%Npqr699W_9n8eq!&uk%V_4N-*`VMv(XJc3wMq$6+83 zycaR4a^9`TbnpFG+vd8yc5R-vBmA7}rtUrDe6hDJjPTAy38vn~2=d;i(XV{|9@CD8bZw4T8M)5%ep22VbBsfTZ_S zCRNV60h!+S?&YuVu9|m1cd>UKb$q9y1XJ(j2=d^Fn3!z!ui2SYIqx!Ldf)pLQ?r`) z$&1C_wn*ajJfVkk#ZA5EAjo@{qhHy(1p`@JuU*^JN#h@bF4mtaa^8i=^uG6Dre-zo zLzjrXwJ5?nK7jC^h9K`(bfcV?Y-?6Ep+ z1c_RbuZc$%J<^N-*{I2{QK{jeceC z3=Cx9J<4x`Bf)Qj;{m@7j;Ved95?!Ha8xm=a^8_w$$1avya$)M{9K#6?fIBl-FxoU zVsG0R!n*+_n0lW;kUzeo`Z`xk*?S%avhaR*PD<7EIVn{S%}J?h`~NfMq*QHSQsulu zua@!t`=5mg_+g8M_w!Tc2M4hD8bab8bRK>TmN?Qj>A9}-bL?B(D=t9CRNV66`9_DKNfMV zbKTUvhlCN{lZfLx7bTc_7bD1fpGLp(`Fm)nz5vwcC9e3#2B1N7Zh^9~p&_SR++$9F19F!f%JAn&~o{mR}w!}SG_^d8Hk%6Zoz)BE0C2kN`4 z=IwjE*xNRl@J>PrrrzlY^4{Cguk77rkiGzt-gYKc&bthm-uFJm)U4)xakoPV^zp{4|2D0#OY)aSu+mx=IYD(AYo6@xtP3cYa*AH@yiz*G4}dbpK6E&1&8ykz((((SFv5E6^W-hC0|y_3HS$Mym zcdf=h_A{w+-U-ni<-HO!t9xf_V(&ca{a7nXFugwS5#wAL-g^@ImA!K?kcGGHmzn`N zKh+FKYpNMw`>AGt?Z=t{yO>lt?|7}Fyq92Rb??P?v3DQp`)kc8!PMI)*4%qE`jx#i zFp!nE$^Eq|CRNTm(%wU zOsbrB=!lN;PQ=XW-qS~lz0;->-gPL!)cYWUym#2m?c_ZJ19{-Rnn{)O4jkE0-V-si zy7%}v!h0;?U4{}&y>}zXd-uMjoxCStAPeu+KKYe-KKYgJ`s7y@_~ci<lPmj=om{zyNtN?%MW%=E$I=Qd?!V~ow_TgdJK|R7x~Y2)i5Gh}QlF3I zq6Aa#Vgz~b)96<|e-FJ)UjX9slKg`ED&H!&uX0VneU+~k+*kQZ!F`n}OsbrBGcrB& zKEv|?xBWxn_1#r_|K0C)v3K6x#POYp5=_04>L8Zc^|r4?A?dDe;z-M@ScVs?_Gp`W$z{oWZ`Xg{tmj^Q}0}4df$65Q?r`) zo_oaJj^~KuJ90eXJq|(MdlmYXz3VZM2j1Q9@zgsLncnx_#?-9lT{BVa-RG<1TOa9c zv)y%G+x23nwqH;F{~u1itF0M2f$$!IAn&~t{mS087{~+f&J#WLPDQ5oy*Dv6t9h5) zC-$C|mLm2JyqEAEj3Dp50R76|r5MQ4`^@balPY)qPP)&z%ii}cz|3vCtLB|QN$lNc z;B#VczXZa&FM_;xGWwOh*I^(Jy!SJya^4A(I?8(`W>)vko-FpZ*$MAflwf*&-s67f z%JANk(68*BgMmEo-o>QKdB;!gDDNehS>1c_1BCbWgm*JaF!lDCV(vW}{mR}M7|7E5 z%->(DVp8S2BOmA}@A;Tn-FxnXV(+}6gm(iL~At zm|5L>{KI1JygLc+GL&HIy&FN^yZ7{V@}7W!EWOX%vY1pkZ@-5-%6k-MR`(v6DE3Z^ zA-oGwf~j{kg1mRP8SUg9hk-1;&pdxGVp8S2TaoGg_hS)>&UI7w9`Y#ReG}oGixNz| zixK3#PorP?{5|v$eF2EiOU&-4rZA~;-p$DLzIVu@`tGW||L&J8_IBJ#cxR#nQ|~nh z^4>?#uk0P1q%VM^_f#fT&btAb-uLd6tnaRxcfd@sw-!x!r=kQ?@8t;c-uuw6?A`M* zeE|sXBhOzQz30xHsNjl%tvT!Ns=~N`tGWE`#vuAZj2zjlTd=GcRGT+_jdFvdv}?oF96{kvpBn=BIVqQ z(z;&Sj_j@4f?mIBb|zKMy9}A`d4Icgyy3qWyZca;q5bO>uNm5`uWNJppJHlO^FEnE zc*ham36DEh+|+vxg1mP*`jx#~Fp$Od+P9sGhd0@ZhadQJ<8a@j8;6hjdE@XwDf&}I z&bttq?s;FZzJG-pgWb z+@te6PrXx->3#1_OwDTEB~OaI9pi}OJ8(YXJs3gWdja~Dy-P8WrT3ZJF(y^+{GIfq zbCQKdB;E9QQk{1v%2@zv18S2L+{-ht^d-d)T081A1vyw5(I^}N{s5<{Evo`{*%y~i&WdpAkcJiKpfh@e^&MF>W+NpT>pT{>2e|h)D;gMAvhi5UVa^8N6WxTWB z%rx9T`*~u4;ePs6FKjlnDeqC3S>1bNhS<9g^?s}nC760wBglJqd%m5#<1mngx7q!* zMNF!kcPlcz|9&hY!?|wi-a}pxdryfaUe9w;f~j{gg1q->^edmghc3|b(X*-unppmA!*s)E9vCo)v539#ffA zIqwE!df&TOroOvs-T^O(z4OKs-l-_T)O$ICy!SrzD|`1`sxJWPZ7Z;GkFiXuoOc~E zz3<)iC4G0*ynUC6y|sG??Ya`t@4X%U%HCaG))#>EKJ)&Xok^ARE<>jGy-zVU zt9hS%MeN;3y&p?h=3H@8?>Pwa-sR|5_HMyI9$c>tdPRS#$axnc)BE0snVQwS54|e( z&Wj?B@Axdjdm4hgcM ztI)6PU5|k*yzf1)c=(nc#ly2MD;~bHck%FdFDoA2eTApqnaFg{`>)%N$FTQTeviyB zw5j*ouFaLdjj379yXG~qcb|#G@g15?c#lAk_g;#AW$#)HWZ`||S<#h4TGmyD-12SZ zEsr0r>|OtDW#`vC^-e{md)_mG9{!KZt8M$|li#Y?cH8D|dlOT$ns>=cvGAPeu;|JgWv$?1*5gZ|n$e9)g8hxhtxL9R`)uJ z{Fc}|Z4%+#j1o+}ecm+p9*urw?+grN;oWD%7moF@UpTsGUpQi7zHm&6{=!kkq{?|m zz9r*5@a5l!v7Wc2XBpb{W8w^L%6mR$R`;I!w%FU|OL#Y+1XJ%52=d2wRGxFil)dL+ zAPetXGHNRhE~%~fZ$@oJ>GQP}S1+!u*ubR9d569&`a6X8fpqcjx748oQ}2Ta^4?*q+sS(d2D0!rJAbccQsuk@-%;^q{ahRCPsJx< zW_9oJYsKDqM+omSlwj(;8$sT?_nLO{o`8Wo@XlgV<-GmYc9i!h%&hJ`@?EjF;|IdK z5G9y;S0l)Kcgt@l?>G$Pf%hUNRnEH=neM$GqmEbC=I-$w@vd{-)V+rkh`sZu^LH*v zF!e4*koP`~e&zG`&~^F(5TBRq%{&;pdH)Yu@tR*9pY(a8GW({Y$`mG5&bt|z?s?zU z>zr!VGj089!~K{1qvH&1>iH2;pzp5Q`|p15i@hCx632HYN-*_agCOsH1pUh1!SCq{ zKzJ7|{2}_MwXqfJFJ2N;xA`iqE^2@_l}VNJZa}7c-n?Ju{UZ(EXZz%tXJXms1OM;Y zcCYvK-Bt4rC=z>X=MdNDsVKqJdpUx<_dfJ1d-p8V7l817?B4^2cX~d0c>jer4^J8r zH#~oiefU@=RnEH(neKW2J!84y`-m~OTxe*so~}*g-?d2JT{Umt55?Yj_YvMnD8bY_ z9YNlEJNlKqyL_N80O4(ReQsw`<-E&~>7KWYr)v{=pJHlO^FFy=>}{jG6FzjVxT*IX z1bOdr^ecO}U?7X@weoqgn=x)=bsg3zq3o2J+W(;{e9ms zd&=2i_Mi=(dgmh3J@1WIZy-J2|1P=Q<>}f)?Y&IRYTkQ_#okl)6W);<3GZVJCR{Gn@VFxR#hjlOZ)H@TI?s;D`av|yYW#jGS^Pz2X z`EO%tR`aeY5qsxR_t!%IO?Zz$koR7Ser4}k3}oSLcK+^M;;DBkGTrlLyW5U)j4919{+mj7gO{ei1(>;Qch$V} zH;cU+4-(#fn+Wf|2=d;^=vVe$hk-os-p{1Uc_(b{DDRb+S=~FkOzfTa2jSg{5=^hp zdu(y84DUS&{mR}s7|6o=^U{e`!}HFqx^v>m%9`{0R;?=3@g&FK zy@M zU$u&N&6fIT_VvBf)HFkz@*jnn)xAg75ZRpW>@7?W_cJhwHKo;KXF1^;C z6??7y;Jw${-%7mJ9zOe8`ywV)&bt+v?!6y-`Mnb*G=7f zNUhjgqr7ubf~j{gg1q->^edmghkmLr0P%UrD}Mc=N^gFx>{Qg(<)63yQQj}4^VSq5 zRnEH^neKW2^ZmJo-*348@&6dUk3KYWz1!bM52@96SMB|Gzt6-tM_1U$tukX~q@Aa9!yK3G6bz<+vW*F|Tga;jS`|k%2 zGc~JuANo@4-AI1^y_4{sh9K`!v`2)v|M#MMnVQwS_k1Px&g(?Ho=5H?yvHHPd#^&jvUfcO zvhbd_aA0M~s5y?0DlUy(`P7ZEhfWNO?f#Xg-kHdB&-;z?Hw^dBPv>1}Xg@M`o7?x- zwlOuUdDna`_O?-fZxFhh@E(C6@4XcL%HFjY$imy~`n>bko_ePu(>-tMdfTx9Vh1pM)R9*gL$u1^U&O83Qj`CiDnbo})?-P5cokd))HKPPmZ=VKp@6qU2 z_RhdS7T#v(?1d34`Oev58+*h5=^}hBFKA(HMW!Y3=HIf_i83p&O7jjj`E&} znbp0=9}s(|^&`B?P=cxVZUlMn-uv6hdjbZs@UD6&D7N&WpxCzm^?xWRHshh7*eoVh z&fD)mM|qFJ%+rf77j>A9}-oJjeW$U9qZrR%Qzi)rD zW$RbFw`^U+q{?}>BGdct$0B}ouA92|ke|ffX;%{7xhTQZyBI;<`!xEM&)-82=?g%7 zUXt_KtI?B-UyW}2-|s(pHG1~8SEEyyR5|ZvWP0B_LEgIv{mR}=7|6og z?ED>c)Kl+VWP0CwFH^Ic_nu>7Z|y?DJMuTedmMti_bT)&d)H$i54^h{^VB;Nncnx_ z#?-9lU2{V0-8g{o4n0nIk3f+3UW$HY?^+Dxfp_N zfxi>pgAwGt7ocC+yA%UidY`!+V^ZbL-$^H(yX<}M0?gdDyK3I~En;s+5aI3j2jSfp zLEbwV{mS0!Fpvk{`K1k>yD9;ciu!+TFczp{4@ z2J*mr7n3UI9sg%Xc`w1t>fVc6#okk{BD|YXf~mL9U*_JU(XZ^Cfq^W&&;0L?RWYe@ z-jS^x11(ee{qZ4*P?IEznxrBxO+x6>cu9zimvByKyoN3& zB#M5M5QU~llxmWsq9!DHsYwz=O)62;ghWwONh<2U{AWMU%-;8V4l~EP?poGz&-r}! zd7k|_XJ+o)JI}H4y`6>teIKNq^7?LkG}ST3zDH4^B!D~ z_ji?Wo#t}6E^@hCXEhx%aB!~?1BVW2e%G*({n`dDvhlr?o+{t1>B!D~w=8DkyNr$Rg){`{doAshzRR3;l6<$K zLdWrq-d`J+5zWr`5lR;R&tnaXrTXUFcm3klzGIbbe9xgFK;KJgr}TZ4wmZJQ8=RhQ zfX(kqkndp`(d>Nhr)1&#u3kJnU1vXkUtYr6cciL~?g~osxy`yJCs-be;Jwf2Or>-(@zw$IuXI?R{f;$BbxpzBf{`@O_s&Gd*2rzKfT(_8qHW<2#>*0DX_A zoznLv+V0qQiBjnX*!X_(g(b}=j$ho|_AErXbdA+t`(#rbnH{HGBr6y%p zyi~0G%CSYwm37LbPnGO^FQnwj@%_SuSK6+heC$hoo^W5rn4S6FbGEhbNOha*yX{#v zzWdTn>3b1vckFvF6*`V@^m?tz*}3|jL&=llJJYB7QhwE!`hHu+n4S6Fa*nm{Ksg)V zd2SouooT1^{WNWN?0YK}I*#vi9{fEf|CK!_SKm`8S@^y;WQ^IF?{()|`*zi~@m;g5 zjqet;Q~I7t+a3E}Plb--`?TgC$K=1F=jQ5r3?&QS_gfibcIJE8dDgxocAp=sRL;hC zUD_#qkEQL7eJ`g%$MHRT@cMV;zuz*V**$;fpO>0);ro7xj(lvo&V0{5-`cm&?(f%1 zm$&gvw{CL@}i@4O37mG9AXWaqv|R<`!-X=CGiI}HK)K1e&|_1(Bqs$-6QkD@}y z@m>A3@y#At`b4v9zMtQ0X20dlmX_GiY;i_3JKr@cXXE>YHX*hi)8eb{V&7Lio$o*P zrGEZWU+VjTbY$ng`(JG1yS|O@jWh)4dpGTrzH41{l6()KLdWqP7=LHeZFhHQx;1%G z)8>zrY#Mp@^rmw&qS^Vbba6JmpZ)wv_Ws#DA5Uc8PhI$m?Rxl`{tY^^bKhMqvGyJ6 zI>!2b@2hAC(D&!GQ~Iv#IZ3{|QK94bzGPhG=El5Bn;&Uhy?KrEYBq1*w^sAVGNRe} zE`3QhzCS49W!Llc21nWbV(0ubihZBySAD7LyEPrzx$l;jTKo20Xmfopq#;1xYiXzS zU8c%O^4*FG9mh9%eLgNDnw{?>lq~$8#~NOm>YH=l^)Ivb9d13%`ud(jLx8@Q(oX67 zC~bHA{N12xx&b!7FL~gnk^^Ig1#wePUk#&cmBX6JhqB~Q$EHa^vt@~gho_kU%K*_rP{HLZO|8{7EqUL)0U=z9e1 zl)hKfcE`RCQ=uGQuhprUK2@^wy^xZH?|Wayn4S6FQ`^ROZ5!WhYuWhjOFO0SMYP?q z@4Zwg2j5j{=jwY7B@5s8wu~`5^S#Au?K|Aa#&_OTHoiO4PU-t;+V0r*Rw{HH->Y{g z*9>>>TJzo0+tyq(cI%q4-)&!0)|;#EDU>`h-*-%}&3^uVu;fiA{PVW@Qjg~wGREx8 z_qsaPzJu4=_^x@ijqet;Q~I7t+a3E}Plb--`?g2#ZFe`%-?@m-_y#j4?a&y{xXa?|6M1-<7Vh@m-g8 zO5bB?yJO$WsnBtJ$NO9zyYm%a?9w}0#|9Q@9jkV3)7Wnr(d?eT^XsOjd}6-$)nCf) zKPG+lTv(3Xe@^bt{Qf06^0DbU^F6=5wQp}t8{eht+4!zXJEiZzwB51q1ytxbzR~OR zof*;We0Q&(jqglf>Pua(>gzwhf&44t==1ai-r1*PVI7_miAV zM|SReVk2wcQM>nB_R|oc?_v$H?{>7^vF}M#=s3Q+Y`n7BRX<(X?8fpnn#J>KGz+$` z(QHjdG&|pUjk59Wd;THzc>O`?+3focW*7GTv9HYYA@lpubY$ngN9I}kPPVhTzPHm5 zpznjUQ(oVVuS<2zvF}k-=s3Rbt{2LCAUvqC=fkOuuiW0X@u%k}@)l=Av-4duFB{(n z-fd^=bMq%2c0bWfzv@f*A4o@b?z?{z8{b#j_})lEfWCLrPU*W=C<}g>vxy zSVlBE-=%%0%6DrzvUA@pn_2q~x3KZOkcI$#uce*RcbTRq$#*L%l!Nba8PV)~AED%l z{XBN;%j$YnUnjc1VY5`3k|*X{Uf*k%n(Y16*7Ne&_ma>2zGBPtbe;Jw-^$u|vX#yCJ%)w= zeb1ns()SM9?$~#Q8`BN2@m=AiJ+US|XZfZLY1?#3xj{{Lmc6lQ$BbxpzBf|x#C+ei z>v86@(HZ5~_nAJ`m(}BY$yVv#z7O4G?b~nn^LO_)sg6V6BWS1ey_&W=_I;QN z9q090yQ`mH_VQKFFMD%TWLc-@Bg^Vt`TVjvH>FRN?0hezi=spqS^V*GqUkrB=GNIJD+vVeWQ`x{!HJa z>B!D~kG$2|xBD6!-`i;j(Dy;wDX;IwW~yV3eUG9-$MJpj#_4Y#`#1cL>2L4;E%pD! z8PV)~*Ss|w-&@yCu>JYEyLZnC`yNO~cJ8}>4;$ZhpEuY@Lx8?_(@yETR`-+SdjJ(W zj&Jn(d~QZGJKvRhWaB&Y`cz*hdOfQz#T#^F=f1n#X5+iM&Go&Ch5&tkPCKRV$~{k# z?`~A+xV~L4y2QW7GNRe}E`8gn^4*$_?A&+DUN*k_+4x>aLx8^5(oX5SOyDH>ZbgNT zxuOKGR{eU!F4e*SLI zJKX@=-x(6JzZx%e_!6u#&zi(Xt?z>OC+eLM&Cd6BN*2EFiv7~lb>_SL?bg2ici8wILqmYRXV6aRdk1ZI?7Kq$ zbOW;V-7zDYo$rm5EPUT3Z%H2+;R<+9`c+qV0}-ml%+4K$gCn zWkj>{y^4~B@B6QeF+1~pXppsUcL$s6yZgXY$D!{Lv{U+CP1_y&K1_v<^Lh<^)ftpN zRkHKFkdlS(dtb(wo%!CAZ|ys2_jum+4jbQnX{YqPh_*ZSy_X8*;JZqGuD<6`vhaOx z%NVmW-&=-Q`;G=|uJ63THoiO4PU-t;+V0r*Rw|T(@3KR3^*x1>h3|Vq#+aS?UKh0X z?Y8q>bEu8)7PM3Po=V#t`(96lj_bSN>+_<)Tz!wBWa0aMD`U*gd@mbj?K^pw&GlXB zP8;8KX{Yo(mbN?gy_^ai$9K5%wEFVjZyC|-p1<>lrKVi?zF(pvADgZ--}6UU`;Omj zhVeZ;BqJ)4f~-1p3p*1p{%Y&t(eGosn~ZaeZ+`JPNicJ6!PC~M!r+iZOA zry)S!#qP$w+tGH%z9&(k9uA6t_V&CYk;s8i*8G#%Nw?~(Ud`;HH=@x7gf0DT{% zo$~r_JUZ1e$G%5Vp&WcK&WL8`yXHNo%J)DzvUA`4$5{Ig=iB(+NJD_WchgSkyVkuY z$@c&%l!NcN8PV)~R~mDwd>eFR=f1n#XYJc-cYUv-Awb`s(@yET^4OE)yBifcj_+>e zXV$AQY)-w6k3C!OqUUDT`{Ae_4f+uEA#vOZ|9%z-=DXp zBRluqGGyc1u(`e$(h#8UwX{?EF7v;W&$ogiPpZogKd0|p&>xuGiayuy@R$p_FZ8@x&c}G?wAqH z&i6)27QXM26Vuam=DYYLYv1ucHoo&|2+;R<+9`c+qV0}-mv}JUfGmAC%ZO&@dle-M z-}he`V|M2I&}3`h?m;%byH84W9QqzXJEiZ{wB51q!&K-vuh-C5oyqA_B|F~>DOvcw z_hpRPneROh+xQ-8HBHg?%4NMDwKoovQu;QJ%y5m?|VbWn4S4v_lUJ`e@7eNHK*D5 zZb3Vx@2RxivG4U%C?9BJFN3DIwhuQe96t?kQmv&0uV`;l% z-^-~`4!(cOh-UZvo&RWR%7yRyB|7r4={oa0f4YtDo;JQqKW5{*D(#fM2h(=Pz86rT z9DMK0h-T-z`}9-gdo~@}x$l{eTl)@=wDEm}h5%ommz$C5jP%`uwmbGciwfo7dviuK zJKt>|KUKab(~+I~p7?~d@1))H_kJ1z^j&Nw_T7%QJN7+^3gzH?O-3|3-+51*D&M2& z$j*I_oNetp-r45*-cCb+z7Nt)d3`sYmFk#d-=nBd4!##>M6>fLzdg@g9Ht5LCeRp}<+IO<6jqg=7 z1nB#7+9`cko^z6XccVf%_lq~$8#~MDH>YH=l^`Eo$oxI1!_Z%7m^u3gJO5aCmyW{8Y z29b0FviyC?u#9MSzV}nI@O@W*EXdB;CXb8~vJlZLJAE51yeOH^C zZa|j4duK$m^Szyth3~uK^Xch2^IiT0Yu~}KHonKu5TNfFv{U-tLE9bst}rj%fGmA? z%!p>^dm|+a-*?Fu($jV3yZDRNzQgz0_|B&xK;PqOr}VvvwmbG+Vt%>-S^9345zWr` zDoPf<@4qs}?9BI}1=hZUqilS4e=*f@=z9e1l)hKfcE`RCQ=uGQuhm(QK2@^wy^xZH z?|Wayn4S6F^Rl(?_!Tz3+rDJuyD#mOz8BGU$G-Pcp&Wcyc{x|#b0}H(zPDwJ*_rPx z3vGOtwDFzyijD8iv{U+inzlRky_E{(;JfU?TzyZWWa0bXkTGUwzSq5K?b}0G?0n}fJ5|0% z(~+I~9=Y7wx4Wv1@9i`M==&h;l-GCTH&Y#R?0Xay%E9;IjA(YgYc4-kz6a8go%`;; z!rFJTyp8XTGz92-H|>PIryHN5zWqbr4^^jw?RjC?z_t>Yv2A0ZG5ky zAwb`s(@yET^2(FsyBihC!S`bs(d>MeUUjN`x27XI_ucYsYv0lHYw9>&L8pd#l*^oH8>ccl`X_ z;GJ{>viyC?u#9MSzV}nI@O@X0rKjuc=kLqcSo==eJ)TdYAwb{rXs7gjfVMmKUG3d; z1G4npJ0qH%@9mTmoGv9kQSo;oEw0S&lyWYlkU)m{sFQV;^eeb10Iry%!Ay?mXC|UTvw`GjkneQzh zS^M@Eweg+zp^fj(v{U+inzlRky_E{(;JfTcx%!?$$-?)&A!E$We6QPN?K^4byXHn4 z-z{jT^gWffJNCVv3gzIt=%!qKkD+AY`+h59%+7o-`^4I}ySUBuUFl;R-*suH^gWig zJNCVt3gzJYw~T0Z&)@lzF(pvADgZ--}67U_8l!{`1-uu=2T~-?;f<>vF}+_CCpN0T^7yBIhZb#c4`<_IFa`3$-BbuG>yf03b z@6mK*=e|dNY3(~|_x!z`h5&sZq@D8mZoDPcF~`0~QK1}sFV2W&=ey>Yr^@$0Iq+uGfC}Z{du~QFJKvSIohsi39of0>E?-;w4xex1 zdld}<`u?1DO5c^gI!V5}QK1}sKb8^A&UfjrPnGZ1bY$ngTkf#-oh)tRdm#-0`d&*r zrSCG^Pm=FeR451E<1(Vz`94C)!vA@!;f_?_ocpf-t+j9eIX1rM&=8>SrL{gfM0q-5dyF1af`U1z?Fe{b#Ed#;V|d>R7uJ)U+--`6l?b~hl_ln)WPjwvn9zi>$@71*3vG2oFD2LZ;b@rrBmF#>k zq-5dy-j^|EXTJCBwe}sXW^;YF{lUg}U)m{sFQV;^eeb10Iry%!H&@?tC|UTvw`Gjk zneQz>TKi61IibyTl@CB^|-a~nm^h2Zb3Vx@2RxivG4U%C9DM(l5zX%TJOAg@lndYY zOLXL8({<*1e$v`^V1X)vF`;`Cw7;90s1cXJNDgc1qu6{y9m$TT!7Le2>eBX6O3|B@6%O zv4%%deRJ-+{=e3~V@+**&!Hhe-%Dwy^nH}JJAVFda5UY3EPr1zEF+qo@BNf4eBago zO;6X^&)=83O1e&Sxm*{yT&}Z@y<^&I#K56L{{L;$wvpyGzNgR-pznFKQ~EwY+a3F^ z_FuXIS^Dms5zWr`c1jk$?~1OHt|BhiNw~ht7q#{s>S^P93=IMLo{y^4~B@B6QeF+1~p=yYq}iQ8>_cQ2OeIP^V&c1qu?X}e?JhpA8wuh;6Fo<3Ew z^SzLgh3|V`#+aS?-gAbvZ;##2V{MDu`0h(PrSCM*!OxWl!Nc0rE>K>hLVNv`>l*IJM+D)jJ5ATz{Yo_(l);9 z(oX4nENyq}dpQ-#!S`<&(d?eT^UI{BT=>3Uq9Y%ht~1~B&$jmMxyi9cHnSEZfO z_h8!Y*!Kb|l!Nb`8PV)~cR%}7`JPQjcJ6!TIo7@-cJHSip&`K6=jGg~&Pd-qXuD(I zv#3xGzBgw?v-92doKxj{G9B5u?}_JH`;OUN-}`9@(08%2*mpbH?%4MvDwKooH5t+D zeCM5es(g>8BRlu~JNfpxT&{DQ56#c-*XP(9syB@4lYiInfg}61O>DhB^+$`xj@4_( zz`>1%-_b9>--w|@Zp-gAy5BHYkro4o2lIQ4ZhP#zPNiKgSLTLef69u#>fLpw-chRg z&>=%oM;?BCxzrh0@z~$QHt$r_<#M%e-!|6a>W;_$R<^Cm^oLmDw^hymAB+7|>*izs znF=xgX|?}JW>6AuvD0y#EO7Ziq#83G5k& zh4%~WeTYT22y8#Z0ttbgTOKvUbwpr|Am;vEV7(v~{8wO;Am(-n^{+uJdQeo`0{Ez&s|f5c#FFO-?Ba^3A&D{qYYDMXeSr;z zn9D1$84ydzhOC5G^ejtThk|RuI+pLCh^L8TZ9#rhd1mb}huB7YeK=#Qc>7HUVOuiv+e1Vo8a82C-0e zQSEPt`L7h%B_7lek9@9g1u@^ktN2Uzp%8N~64*?L1>P0dYKX<(6WDHuCFDU%U4mvB zSu3j5!PuJuGawdxUtl4KMPC)zix7*)1@=jsNh`Ih0*u4--elM`O z5cBR6*anFCONoXgA?7_zVCPpw4RQY?4%!4_k)H(C4`Tjb1vUj@t{(-q1Y$9ln8H^O zi<~a7BA20=hK`DZR)biuxTw}1VzE7<+DM2+cM9xji1~L5Y%RpRZZWo>AQm|+s+GMQ zH6$)AG{l&^P6H70ogv2dAjT46Y_CErF0ZUFAm;vAR67E(Kv6NaORqo;@st)=8;H4z z3G7aYxl0Ia7Q{UAf$JTJCFFIw2V%j$L_^9{Lo@Xr5?Eb`g?|v(tq=?D7uYz6C1gWh z!kBa#hgkF%anL^@7MHRvs*W0x{7qE50b-$~!15s$Eh*GbhnPnmbOpp>zl(!@2QlB@ z0xNMPnrY}vF}AB9mXy~*7l_5mh-zaY7Cj=yHVAF?Nk;$Z0jvOntQlb|u7;vRVg-c`J)* zqcC=@z@CLz_(FlLgP7-XfgOODtAW7E)j|ykdIWYI#N6iztT)8s@}QF;=JAPYQHc4k z7uc5&^Iamae<9}16WC?7QA3gy1=bc~;c5aKjF0joIOUe`JFNnqJifSG&YDnmOf!zqP zU?YJIfmrMUfjy3~rUF|9u|Oq(?SfdmhQQ9e8qL&ok-)Bon74(%x?$`}f&C9+u5$!7 zA7XKdZGu>&tf+PnVxcAiyRZ&wNL)6g8N?zNi)sTQ7CcvAVTdKF2<%OWxh3`u!~*q2 zwbQRbGxc33u$mBydIi=AV!m<$y9Z(k`SkG|#G>Uzwe=A5R}k1Q5c9}K^73_2L!y_8 zYK|pTrkK%q1`9Z4isp6bE(HLo*H564(_G^VbpB%@A{6C9u07 zmXO#Shy{CzYVScTaJRsIgqW+Nz|N_U8WQR!um%u|_7&J|5c3Tc*hGj$0s>nEv4CG- zpF_-di@^SYSfY!-s$7d2l4vck))4dc7FZBs{p0%F0=0(%=`;r0Ui9%BCf0xR7B z&D3?9z^;KXmjuO}ch{bLe*e4K+=L_r*#^l&4H$)Bbb`aHCKrGru zV0S>wGeTgGLCil~U~fSzGFV^L#$)Am%XzwgqB=K>|ApvABG|ui6APBq{fxzhM2dfz+wzh=qoUYG+-KW*WUyVD%st9x1Ty5R1+d*aHwt-Y>A1G4_QU@IXOc}`$EAr_n~u#!#D zOuZ8X=7m_|A%S&;m}{cI?t_?bvcO(|m|GrnBgCQ)i)z0^EbyqnE@*}t5}G2grVxwF z5ZC~S`Iidp5r~D~6xcF|dEOA%4v0lw6S-&&LZImFKp^L;L`^ID*W#D5Z49>kJ+1l9*)o^1kq2x5`_0(%`|v4aBJ zim|T*_8-K;e+caI8&E@h{|Kxd#3FwQYy`xD34uKYvGCUdTLUrg4uS21Sag@b+%3^e zBi{<_T8IS>39Ki?eBTLd0>nc93Tz?75<3O<8N@=n1@<3Y8Cd7gV1hyJtzMloQ8)EKX1XijQnrT8}bs!c^ifRVL5=R6Uf>`KRfxQSZ z@1Fwu7-Iha1oj8Sk}mNPj7qIhLqeActU1JD)dV&OV%{18dlX{PGX=IBVxc+$`xavU zYXnxj4Vr1Nw!msZEO4#BIzuc{TwwP?%vDxkb0L;!EU*m_^W_OF39)Dsft`O7YDmZs zSQCt0FR*?P3)~^FDG-Y_6W9`nd2SWhR}l021XiRinyIUkz^XyadxOB*LoCojU?U+G z>@BdTAr@~bu(c3#N$e+x1zU+~W!s^K1Ud+;A;c101r~sqH(y{6LM+l*V6Q^V*IHm- zKrGTrU`HSp?jf*CZ$=Gqw-Hzyh{Xc}yAxu*J_4HsvE`ig30+M}69 zZxUEti1}|9*sU0AC$Mo4^T?UL1TnuUs>LA|YcH@rA?CeJU>EsOLlUxYH$W`fPgKi? zSlBPH=@9dF6xa%gCFR55cM$Uo5YW6xdY|OUi0pAQqPos$(G*>n;vD4`Txb z_7TLq(*^b$#C$=4RqTiw5*{xwAH)I^1a>>bqQe9>4Pv1u1@;ESJmUnm9b&;T0z0h} znyKdzfn5o)$Pj^bfS7Brz(zsLH&$TJLM-;Qz}7)5I$K}|AeNLfE!P<}Bs5%9yAEQB z`vle-V(}RQn+&n!T>^_jEc!ozeF?EpNMQd$%p(ta*)6Ccap|-z#KO;rgARw7ceKEs zgjnQpfxQbc|NR2ni?OE!c6Jvu)8J5n)rVO4Zh`fHSa7Dm#zV|KOJJ`+EHFx7n<3_z zBe1_9=Dt&4p021NfoBDFBg9u25LxjbEE%X zVnr`<(hOq3H)shIwHC@ih=m)ynp!DE@nMKXuBU1WdlO<|A5~NQHxLWGP1O{3x`}2Q zpO9KiMq@Q0=6hdYx0@wh#au2|t&BBc{OLbpR|oBMw#(&e+b7@Cd04L@!}I@tY4B$$ zdL@hMzgXANV++?Di*_73;{S77C|8~5)E~s_+_8H%9?Ny=(<^`AklRb&ni^>}7Sn%~ zuVcs7zUeY>_`u!+^9PO?eFLRxu#{et5arxe$um;ceJ0-9>}NHvCQ z(hCCVpp~XhJ)ov0q)Cam2V&t5NRz_epwaNFNq@9KVMx;figHc*a|}8vHC64IY5>=y zKPI7bLX$}`u1SAZL&vzL>6GG{^twtqRY22c6cn1&N=rIurRndUNK^9W>rxNzO2j3% zAuJLnO$uuTvG`8{8wxSs)I5IBmv2MYrvA)`Iw+F9lcHR@{(y*%O6e5?NV@*~iOvb> z?J35k>kq-`7?(bYQe3)T{z|6`NMBDuE?qB(rGr+|e+eL)(e@-=X)WIiVR4geDy%~< zq)C5#MqxBUnhsHnYto+w(lM^-s@|#j2~BEUF`X)) zX($D`CcV;_4q9oN*&Fpgcq3_2B347p?XHu0O{K8i5Q}ajn+hw{2OTuFQ(!IoAnE#Z zNvax>eji1JboC)59hK7Gpd6R3KjWlxLi$e>tniO8UcnQU8N&NV?Lxjt;}05cOxT6o&f$FGYF(^#`qVRQA7Kzf?kpIZ81Mf)O7V+MFPNuO1^U06f};Ow(K{Wq>VK*Ju>UQn|LS^a*&m(%`txN9 zL;b&xqP+k5!(=)t`~L>zME})i)pSnu|0jxx{;Lnn=@{>S)!Wheua_9qsRI4)OF`a$ zz38A0TJ`_o+fo0$9jO26foL5ahM)iXGjs|={r{Juy#M+Gb2=*fUvB_B|JCR5bWZgD z4vO*q>kkF$81Mf)N{RDdEy}1<1^U06g1rBFnMNJ7>VK($u>UuxCmnh%R|jIrqv~mb zu)zb-WuiY$s4%4I1&VS_`m=*NDm87V9KTHTM-z2UXev7>HBzoge?C&jxTc#Z#Wm^G zE_JGariUrWHR<&)bZr8&GUd2U{b5d>6E+hR<2LmtN_C9eteBsgAGfJj8`Y@-HVq1Ln|l3G z9kj9;%18ZA-b6N)uNNWaI)h&6DePm21s9M_h5Z4sSPOx92P5g}PqxyzgrpCkD3_l8 z7^{j(>CaM*OHY4FR^^2BFDS;Pr$4HzVqE%JLy+|JqOdAeK>E!TFSYIX`KTxPeqchu=gMqy^d@u>_>?CPZ!uZL($lLN9cr9)fzy|J6=>9J`|lo`UA+S z8ajnup(sCv^rww=RGvaRDaTJC{b6RE6Q@vxU}~iN6w;rl)-iqxb)Xb~+|Vll>r{bL z=urytQ%J83tb)xEsUt!6jU+lC=c(bl9% ziI@nnyIQ9TX!@3dT$5hSS_iE(6(4~#dDYdVMAU*TbE~rVpWvxW)rNi*cM6W`iFw}p~$W%i_|J9NMIx73$m2$lQdPM`B6aAk`G2VZ@ ztb&g5{;#7H@4sF~U8f54zxds$+427Ch1GS?s{gg_M*R=AqenCKlA|-m&Zo;nVUN&g zxF)?IgTj!e4=Bnt>D3o>RBHN{a$J*M+(GArrn;lhWujM@&@rxQFr~OAy*|B870|SZ zf?Shcv0ewQG<`k_X-YODO-jT+5OWPAO$w_&IyHH&Nv}HO2VVq!-)JF|MiHJ*oL|O?u&fohqQIGX=ROeJcPRw9<6%JxEi~Pnwj7 zxe)XIF0dUm8m>t%)1j&%P3PU4>HycI*W}Pqsi`gHxF)^iht3I2<0!^8>2*hRjB8p+ zDXvN1Q9-8)X!?hOT$8@Xf(}|~sxk&?iZ-YID-k`$pvy!rMWQg&|HmoH`>)p>(NWp| zjg;g4*UOsdoaleiv8j>r{_C|>bd2}^I!f{W>w8e>RDu5AOF`a$eOC${wCexdv9SLw zssHK+*bNX%bfHHxg%!IGY0|5*C=6-JqbS#;mtfIRscAUnxF)^Ai_Qs6FHwwZ(#y=~ z7}vCuQbLouxra^_&{XArsm5?k`gR{WXr-z3|BxoHej|%S1R)l0N17D&3XO(8nxz-0 zp=wCeE{bwZ>D6ddRBE~)lxl#`q!+tUIibl8RAS zmvUT_Ugk;Xgr9wYGjBDyjDXvN18A+!KXnKNzT$8?6k`7vFdV2!W{1xg z^dCjJCcQeBj!I4SC#4#|HR;8_bWUi>rx@3yS0K|duIU9zaZUPOUOH7k)AtnQn)Kbh zbkIsu>B&&jpVWUP;>OA7GSQ2YDGc@he-!2Y*DH|esOnb( zYdXgJf7wH+`SJeiyPxS)f&TZSAn(7vADRwY^?%AksQ)o_nW$f`ErD2g1!+>)&oml- zndtS|6oxci{&1=TT$5gmO-H4s9+cyn^jdE^Cp1l`7}um1oYOI`X(Oe$CVg8uohqQI z^pw=>xF&t0IUTgpbj=i`DfF*;m?9A-#$FfL<1`wsNiS8Wsv%9AD9SbIb?J0eYAQB0 z)c~$ZFMFqRLQ^A(aZP&dJssnkhEs}b()a7rsREjoP>^fVckt6eD@|WbMVfrSt4A{u zQDhpz0?!I8Z(6EnT$5h4PgO&jMo^S%(o6K|sMPcd<+vuj0-(+bP2W+BYtqXQ>KNB_ z!6T{paZUP0h&ok3lSx6YN#7b#2dy;S{|M@T>>%}DiC9I4;r-Vu6Dkb#{~$$q|MfD2 zIx72LBaAK+y~?4^iT?MZ81KJcYEj2{|DU83@4vovq)rv+|5p^`{ns~>)IqEM7kL!* zKU9QXo2kDY%6k-@|9bUBg`xhBpeXOZUTRTCW&dBH96$f{N{%`w`u`opc>ncsk~+rw zf5Btu{MR?z)TsjfHz~;buW!GpgI4{&|1s2m*HJqE)gNW8qQmg>U#~E!Fx3Bp6y^Qb z%Sq~}?0=2v==|5KRqCARe=myh{_7<(b&U7_NlNkaU*Dcorwa7{D+==d>l>EppjH2i z%s~B*{Z0K>e+ij41D*frRW#`jCQ<)KP?YySy=10}%KpDXIez}9SL9SV(f{u##`~XM z7F5M}|1WqPo&V_@x~f!x{+kpO{nxj6RY9x%-~Tx3ze_#-tB-~)fLL@RX;RoO8V$cp z^n#)aLz*s}nd$)7q*o8sQK_jT<+vujIH}GFO_M0bHR%;nb&P9zms0#P(Ra$#sREjc zJdv6m*QD>AtAkdWsy%@;h5n%aD-rD>=AS9Bkq~pgOrNAy)n2DTbDMezR)ry(`zXq7 z>h)H2RNC~+O7)4`)XTZ*oUqx2V%(-)Q&z{g%||H3ZR$G}>r?@opHPt7)b}pdK`Wbw zW+9s~^^?BxRe3hTBJYt+g|&cKYz)~{*c}i{78lt3*(n2Dx?bB>RYTIhp(vNG7qZn+ zDgC@Bp>(xQuFeVRH&KjB*NgS)7?(btQe3*ep|nmFkiM3JT)Mu+v<_NH|LI9&Gp1f? zD6M6mLRkD8lCH3Z5DUkfq~6n0SO8+)8fwi1I+q@VSg^goUWHg>kihmmg-#*81hG0O zI)yHolZx_FNUt}nqw*B$Mmhetp_en(IdKY2qZmJh^qR^##!sOSD8)}9eHU?^DsT#& z@pNi-{1npn71u$lQ>gaS=-lufqH{x?B)32;_JzR0G#Y-T>(!W5HKb`hMY$%u^szvS3@0nEJxF)^4w2pC2Lny^H>D#mGQ~^z|QjlxXH*D8ID@|WK12z3c z{Z}H6KrGObt|oL_7~Mmzy*x>>C=5xSG@& z-3mjR%0HLt0N11!gHRi;n9U*R+aKTvPCU>b6c5&~$`? zTvPN_8MM-L>0G4A`#Nb-B6`k6mx*47Tw$pHGbzgZuNNKHQQ7}Zl;i!^Yntnv=>KWY zr$#FJuNGF4d9yeO7}V^G2N=<7h$2I9i|8-7iI!rOHN#A)u z$GE1e7o_ILHMw?Bw{@z3raLJpG!>!ymgu0BrdbP6|C8!TM~V214#O`KeKP`uq5hY8 zDK$0Te|_fx9hLoWMmgSpePaWi6a61WG2VZDcLg2e{ePWOy#LAnsQ)@up#Q&8koVvJ zuMArCzrxF?|K8Pf{;MBguZNhgEEc&XBjuX(jV5%AYwAWRt|_pWx~)?MG|i$Q*W~(B2CX!`^9s@wT~3;mh&>RC z{UoqU79vgh78R-*(qvFnXj1p1&{3%=OgXMe-|j-^gr;>AMll_yemkP5^*cUqB{jPlSace>HE~EYDm+^6y;ZwzA254N=>IPNi~3L z()Ya4Iicw~ig8W)#ydL3HI1MY*A#QngOW}a(6p3-TvOz98MM;$^%A5hsWd4OMVBHh z+>5Rzg*9H9>KWIhZ`q?Tr0Fh-a!vaFJUS{hEu8R{~&1L8^(YH9#Inn>#6yyEZ_gT_0-v6g4#rq%IL;csO0{#D*g1rCHoib?E|DtcA z{s))P!<72vT6KuU4+^aBo9HspcW6@8kfu2l<(l;Em~>QX`iye?GSPQ?(mA22r??v<0!~AdEIoG=%AIRmzG0KZ&Cl1h&aTe!|BmXVWr+e zn)J=86oxc4rzqE??@XnmQqw(@bB3E5(E+bt5tz>?KPb$peas4uE}?XdeWiu-BQz^E0Lz? zO6tE7QD+spOw#uzBVVZhgDA@TpS}^9ipu^!M>*dA^nK1$PW1mvit+xZZ?>jly#Mai zsrm8#`x11S=v0CJ`zgr#A6M_&=%CeQa`$S~|KKX>zxvyu#dH{c{_Fd%DGc@hM~d?P z>zl3VsOi?f_qy9(Vrv9rx%Bu4YI{)=O<`jndKZv5d|N4emoobpCrvQyX=vK>z&|Ng-yK8!cd5TRR(}b(m=43we|;Z4g`xic zNKxK@ebYQ0mHofuU3C8Id-Ca==zmv=@&4-@1L_#>f0$C@{4YUm)Tsjfk5iEM-=lsn zpo3QZ|MOkc|G?+!WfI-`=b|+TOH32k4G{CL5?E*rx|;Nz2h~B5&E*v3HuY@=byV8? zg>w9A(swb`Ibrj%_fjL}HubF(b&T8WNhxkKq24#ssRA~ip&+*z{7b!BBO8`B-+vEk z`kMN$eC>x=@(F=mu@-4c--MCuBTctalxs@gaZyF3rkRxEn$kCPR5_t(BgMF;^j#%Y zjB7gm{nY%pChsBjq_0v1G~GZ!t||P33|d`u`R_wbo2maw#B_+co)g%|G#dWcsP9Lq zsv%9q*QGkZHR+pA>ZsJzm~vc`zPF{$2~EQ(#x?01Z0Z=-w2)FC880=mI&;w575=5Z_TNyAx(=Y$~EcxaO$Ykw3~8VlfKQT z&IwHytWS-UYtr``)iJKA6Q#JOgn9|5Qw20lry$o9{e}GMpp~W->!BufH7OB)&|&yx zqHjN{Fx3BA8_;EIJ^SB9hvEI#w^&se>i;5&^7CKcPgO@{|94Z4 z_g~+xRp&(iFZc+Z|N5S>I>!6oiBi1(p(M3Yrwa6cIt6+Eqb2FJpAK5}f5k_r|ADWl z|LV4k-$5)gqGjrH3JNQ+5mk##6j<|(sUC5g`lht18nSsWMY&CV2U;DKHWyQl+tfF> z)j45vFU9!Pr0=q;W8CH?n^N=RHa+U1(5V78dr^?vjQvihfeu>PoU{q`-}438RK8w= zSYj4wQrM3)8m>v-pI2c>QYUK@2*tQ2eZyfLhRCjxt4X-<+Bs*AzWMSCdW^(A0&3TvPZg(xih{n#OKMngTmWlM=C< z4#WGe?@X;Q)c+(!dH?losC88K|BBDhWuotLt#hLPJt)TeuWz-jW4!+}DaHFAIGft2 zQw93Jg@U~Qk#9(x4qEm9=x3<^iEpU?>e;`+=ji;`ci&bR>VJ@;y#M-E+d3-y|03o1 z`LFNft#hLPJ1EBcuWu)=W4!<6zd+}|`#Wl*P8H~X7Yg$J2fvj;tNzcTd|h@!=%6_* z_1a9`8M;$>m&?_647w%sSFnP2FjY`DEw-spX-jJId<^kEssi0l*QP>GSiwDrDyW;Y z+Ej?(3PY)ax^JjWg`KcMxCd2GH=(qtQ1wgH2Y*LZfo`K{Q=vbs5FbVr)QtdbDlEVi zda5yOOWp6@roxY~LU<%qPO)fXLEYKQros?dA>NtBpl%aoQy~f~M7vN0 zb(bKU3ctY$$*xpE-N44CLfvhs57GOmg1WbgO@)!LLh>G}plb1?*24;MH3qf3uT6zBx1&A;T{H%@ z@~lmTwy;9D1XWOrqS{oL1}nI$QU$eMr%i=8tdJ~E71WB8HWkY5Kz;CEsQTckee(^+7GAWK$slD+DXjEYvDLHWjLTi~8U%N)^<~GBy?Z!U{=MK`m2a zQ(-==;4V&MP^(nfRM-nEL`zWxwSa<6g)0-N58>0Og8FQ~O@(||A$U4fP#-(DsqiYS z5LJCpADp(Skc1WdXV4hbXL@Za)cFqf;e4u~K5lALVFav@EUhZgCn0SrEQ1yN=THUp zSw5QzhhYWpSyVxN%*>`jqn)S^!LzA?`UI3sg)y*#_gqzhKAdAy;cZyKtsZIB$4hJ~ zxOTx=R8xJRzizat&dvTiz>tF@fN~)m#;@PG` ziQT9VffZCi{V}dhg*LE4M2$iHov2NPDX>ClHH|_238PJgk70$tJ5)ja5uQy2_xGp| zzHU@O{TZ1}g^sX7%%lqH520)-%zzbKy{LlvQy!ZNTVRD)Q>vi;e8i?gg*~Vbk>*rE z{bhqq1rt^X^`r{wm+m$d=HLoGs-S)!Y*XPISRrvcRZzdtw5j0v0rkP7Y^vYM*;MEa zEBJcQ7}W29Y%0uy6+)ez!{r{VG-3CHDwiDyVEQkkoVch%x;=UgV z_s~b1)nE=`d`7os$9~$8xN+H!sTPT;E^nP`k*IEVhPdY~g-D@%xUV)1=GZ&WnR+Y!gy!s8Nx7t$L@S6V-o&_ZH^gIV5~8{}AL0=; z7;k0X(Jvq#c!vffaHH6MG}VX_AaL^G*d$wZS>y4b~o9>0w6a5X-d{~(^MhH<0zZ>Tfz zt1xc%C!FhzU#akV7J46thlyT6xky7kiM0@Ss}>2|_#NWOTDZDd<##maaBad9;#}(h zalfiAa3ciqSRGv5d=27}hJ=Tk@y>h$@jzpY8)Xinsru?++`NHsuGf=Cc%Zt4-VyLH ziR&rnzl=}fd5A}vVBFXYagXY#sBRYd1I}3uCUylMj2Gget7$L-H*SNtuMx)0X%Kg- z6F=IR4`wyS!<|wOR022lV|*gU&8mk|o#A?uQwR?(a{Q---~`Gg#nat5i2EPJ zxbZr~z2h-%CLkW4MtH0)@95coqO&2X1|x8z3Bx~f}uVJD0 zoWIeW-ODNGx`mRwH;zEuy9wiF zjek&QqVFsGN1Cfg6({?zX6IzDqdQ8(u?$ah+qKHwh0D-blH)%F(-47au`$ zj=zU-<7SMn$GABb;_eR#kCf#dT?lcnsxENjYlsKNc1fLU0yob*il!PEMR=$QA524t zhel%D7y$9u-556`gmb-~F@(p}RVd%J`UD;(GMaLci}@t}g?Q*rj2pH7MJ-DF594Nc zhH;@zgt&hK#?Ai` z&hDS- zFoPf-o``W{HpJcIF>bDhcv1<7dih}fgn0OVsxENj@*=1+!3QvI_9UF^^*^GyaPr>CaM^#;!-JgI&)AobovIsSuD&_y|ydc{pw?>!Lr7sa^o62#*r zF>Y>!c<@ZZBQ<$P&nS-cCeOgQQ6J*LjuCfF_r$pI9>l%3V%+?P zaIV+eg>Ziz8jRF?ZcEIM?gzMR?$D3%w;vqB%zb zlyi0DlV||(SRafVw?o`xftxcS9ve*6L;d(*-iLUgFUF075O)p2xOwTBurmse_T_`= z2=Tx`sxENjeuzhgV%&U-aIQBro^an#3%z^cVSJM)7YXo5oL>sfIbnetEg>Fw7*{v% zf_P*c;Q>D%%shw(?#HZ|<3Ttt4>cvNEVe(Z(1zJ44*xkZ@mbK9~nE-UQ>u zVu**Y$GG_&#J%ka_qXMPai0aJ+7{!+^$<_C!?<}j;aqR})jWU>?TJYapI%MYz8|A53qE`xX6t<<86a+vkT!uZ&SjfT`lxZfQLzzSBJTQPhu&=<5e(j?1Fgs5{#Q=&w+D3 zmvHYWKA5Huk6(dtBM9+uC5)TTLOggW;jx?fU_OR;@+yoQM)v_#`?&Jb58aLf}RS;)y-IQm@1W zZoY=`?S#A4>qB~vq>j+;cnc=xT`j)X5`o zV?V?_+i-RB!iuOffv*UU-Ngsf2I7&gF>Z{8c;ao0o39ft^!`G4c%X&e1U!syy~=gx zlQ{bVG-uZqj2lfL9(x_*=3t2X-XlCXgb!v8#9eDJZhQps&}SGo|Ax40HQ}Cid@$87 zM4j<`h;gGE#3L5f%`o9yZ|DuG9#`)^$u}k6frs&_vnbMuPvU2YCpOVx1a4HWgytOj z7~^JJhMYT265M?RNdE#ccw&TG}YKLj2qWt{C$j@ zLkZ`4Jqk}+y|j7;9>(V@3qp7-s@+piP10WuL4&&w% z5ckd{Jk*U3W*x-i7P#>T#KTYE>SnD=Qk~&?gU=K0F)j3VryT#mDEWe#^B_Knhanyx zk8xuK#QhIq+}sE8V2JRzc%!I76?8Vlr(@i>5#rIuF>a28cz6=wN!3xhdS8Hea5lz` z&mkV4jB&H{rAV)P9^tV87J9FvoX|T{Y9z;v$1uJUWH&#O7G&-3kwrc#B?=CFb!-oKYRk+5IGqO5jF)hzGvK)y;kw|739Lm00W% zKA0I0Pi(=s@gBqjA7b464dSkk2#-hjU@o~5btdu^#tlEjT^6`GiEyshvz4kxp0m*V zCOnMqYsv-Z@=5H0cxXMwjq_@tIr~1vxY+{YF*OPA1U{JI5RZI8)dgp*^+Rs*Rz)Jz@rv=?}CT%y-K;z6h4W05RbirapN86VBCBJ;(^x*_b=sxc^l%P*D!7zfVfX}MpQR1^QJn(^}5zk_3)b( zdOK5&|6t^aQqJ=RpTq+YcP+-au^8gM)fhLw!}t=yBd_woxUWWMgG)U&2;8_H;vRiA z@apCehzFL@V3MEk!8{G|Pz2+~Mu@xAqo$~C7OR8wdfuSwf#nu@ub~{*8&Ri4a0{PA zZ-@t0(qRN{JPPq(EqYH(;ARZs(N~A1URs5};e+`F;=x52H!ivcoejzL7&qHN+^q)V z-pU6v2I9%rsJg(7S0L_Qf^l;f;r!}#uOZyOwPtE*TluDB*}7=X(T$YzeNH)gZ>A~4 z;|nov1R?HM9TnBhXCa>4MAhRz@xgoy@!&@oH;zKw`ys~7n)Og;!XFc!+`|WRE5yAq zj2jO@-2XDh%{7E`z1~j<_iVG!`zt=oTa=6J=acZ%hjU(maicxN{Yx=!-UspcGQwjA z`Ct}7JoqNYjqMPRs}_msW~pn@RD%mt^{@C~8bLh%KE{oK5cjUcxcMC6TyOF{!oz=9 z=#9g}L_eUM?;k#i{~#WI2jfQV2B<}GH3?DO>;duUa;hHriw|ZB#Dl+M+*k?m=oXBd zKSDhC1>wO2A56uDXsXFQ7&lr$+^q&9s+%Fgx!$;Xd{?%Fn2)Qzn!WJ+;|e=@ogA4H$dF~2jP)#`Ctx1-2ExW zjVrE$o!NnL^ESe{-e`jGz#$90)8Ju(Us2BY9iPN%h)2K2xUnDN@!v3RUYLjG9E=kl z`j-!;4aD7QFakG5L)^a^S2q_xJid$Y#7;h#FCm^()dg-8Zw#lp4_7yv5YF}b)nh|w zw}sxp@G#;1bQu5ld=hgYp8N^p#zzo$|AKMzZ;1PogopR?!BlSoTl6!=jcyQ+AHlf! zAjE@53HOMXR?8qB{R`v9_Yn90jd8Q`^{J_Hz23cq$9}NT+m>?t2czI&$^{Sbj@}D# z|4fVBF4>a5O+@`-1jpdObH*->yKdExEA8U*%&wbV|)hT?qB#|9*21JVT>DV zAs(NGaq|e_La#bC6KXK>2csHIQH#P)&|#uUJ_!@zUNtI#8(b>o{Dj!d^0rF;3F6}Z-BV>X~ILl^1+P2_;idL&qF+JQQiESaG`fHRrmf$gOPgA zY>ws}o7qM;(GTJ4ARZr&apMn&2Pa_M ztl9!~#;q>L&}DouognUil&TBd7zc6p;}|zr5YF{R?|6YNf zJdAPUF^q>XZoUig$V|ecP55Av5D(msapU4Ps57py7&p5T&h@&66CN@w^iG6_iQTDk z*Yiod0rAMA7&mr9Jf^MyQQbWECN$@m(i^yg52hK!efo0bxN#@MW3y@O0yiTN56vPx z){GD46NtN>!npA-!~;)a+^pX=)fuigqV#%hwb0v-a{LD)&oguwzmHF12E-$mV%&HS z;;|MOH-Ce8;zq(h$X)ppec0fGf z!?=0g%}B3r4&i|o7J6Gyj_XZaL%CpYK8fKF4_tw9V=lyFjWBM03UQwrOuQu@jH^A; zn`l7Q1#Vo0@#+{idqO;L9pNr9n5hu=)WEp03gV&W7&i|RF0S5cga=z$=)KerTU3>D zfeyT*9U&f5lMuLZKg2_q;p%1-;;w56Pjuyj`4-}#CKxx)>VT#iX^C;OF~nW92>0gm z!Q?|cQ5)mNQxK0>R5w2(oa^W^{rD~xv}+H;@fLENRzHG!LV zL)=%Fst0=V!OX{abBr5bKs;el-7M1s>GkMFs?Nv<=RC@By@94Qsq{QdSKib4RKd-jGGHEzH2=Fo%47; zm@gq7Ie>AacmPc`_8rE}dJvDOu?Hsb!SscA>~E?raAP{eeP>W-1a5vrIM*AwmGI~= z3%!5C!?;u~^dz4|^d@#!(9{Z1~3*7h~;)&fD zH_P=#Q;qydcyJ6KOmm2bzQ?#R4C0I-3%&o>i~Yq$QN(coA6gpP(#jSLAywo+sMcV+1qHQWE(*4o z(wu_P83^3bZ2w-{ZF^U&hO#J8lL~GKDg=RzhJ+Ym*64!|O;`asCRZ^W5=H}Q#m+uP6l=J%W5?B;gmgDN;4(ca(SG(kv3_(#lcp(cWP=O}v7}#k3VY z1$pur%=vl9o%xuH;x1IPQ%O9hJ)BoT9xTS3ry%#1V=i3C<12`}C)D=-4tcN$bAAhR zd7o&}MNRj^l~LR4)lzhGB%;0V(KzkJ=t&yqeXSO;A97ZQIsXN6Pd+}i=;8|Gae4P9 z_NmEK^`PAllkL?wk3$|bQtlcT{gB7xSCGUpHJKBbuaVJJ&i{hkd0&2UQ@JQfqxQz1 zqUd&iM0;PNacXk z{37J`D$GU204mjenYj0bnoJ|)iF(X=H{`}@%*FS_wf4#fRVcp*=wGcS@ietGOk2iyfGMKs+b+D7_dRfIQKIIUk4Im$_@v#SO@fcPM)BsoLJ^A+$1~ zOh)5;6XbppM;H5uYweXhKSs&u?e*a_VV0&z98`(@)}~ zRLM2T5(%gbCRPQYOHq)wmFeu$&rczbP-r?OX%(t?rCJpN0I&l9*aHAu@_yY%p@F~j ze_0rSB(uLL*4d|@>37iiVzb|s?4%0UB*$r$YE^J@oWdWDIu5!!6GFB0! zmB+?iHnVm#xy>pJz!S4y6zQ*!YyAIp1mL^bUi(0`N*nDDb1QB4D}%zcJlVe_0HChf z&LV#51dV?w0D#nNuS1|xm7rDlHvjd43@kzq-hXoSAZ2(bBrG~pr-Qls@&h#$5E`Rl;=t4Q$IT^_3-c!Ti=%9G_e$di=uRE6LP9S>NXL41Pk znKT0#XAl}wVNz(hRsoMSL%IY88*?%3FiWul0H9gRrXHS6n|n0#lr(SNu4VIfEt@rI z>(Sx>a*c#7ZSK0WGDg9YD);VrWzPuf&cyEo00@xBYlGy8iU@+TUJgvkzQ5|1XCg@2 zDafH04CW455;kdj1G%CYS5--_xQW}`k;$|>Fv%2WGV8n;|q# zj2Ljfx03}qz*!*9J4qRDoDh^Mt+Dw2DyV&*|@%HwI+gnTv)RemgD}iEO6X= z$Qo*GCo_s?I!1G;bdBOn(ybWtGG??O^8zDKAQzsD3wSEnTcy+nh09|Uo#o;1Tn*|T zp-u>kQ5b*ho)8;`t4@I5I&z!Mvb}OrzGS!__f3 zGuYbSkr`@EC{d6~9@j(FStBP82&>`c%%t4nSIWjKj5xU}NGsQ9jm7I`+y$p8;}6g- zfYB9z(a1sbUrPLPppGNj`z2pF2M+}&kiA)V`6k3`)v?CVd&#v-OR;yC{oL*kUBvVuIRyBTfp{G|GLaDy7eu^l%PFR0#}HUv30#w%Ge;SJbW0-X^XL+<--&b z4-a^7`n9P_F=@hMbJ1REwYIxDLXp=nt zz!+rRlo{4|9?n>^8~{uS7?3f-5DJi|J-6ZQ z%2*u3%sg-if#de1EC-bXs`1$&<@$dW0B<% z3Z9E~4om8u5EIiFUTLB&U)%02C#vG_$}#GpYY2FD5~Li-;cTHlB`I$KLV#M$wCZms zWoApT1#K_tGlhc(PxA`HLc$)38H-BzTV?MfJNC+|BNQ3%tPpMaDr;AP$;YezH|D@#JOm>UdPGLXE40SBzK;T)>$jkdM;Ycn zjGf4GLcJ3??#eiZy=HPOQzohf`z=67%_LO zRP`g}dZHl9{v^vE1z8RtS+=Rn8m&Bu813+aEQ!%>F36G??IUD~rhapvdT1gP8e^6i z!s}LHvV_Y=b~58Cr3u8KIC;3Dvsx3Nj8$rTsA7^ym5M_?(8U6rNb-DWm64GuMSOfe zG2 zkyjgdoh0Dc`5JjOI~K{*@mg!$)~UwS3|%6aAM4o-M$Sv}^!0ejnD6|K-H znagFu3B@#IWp85~5RX9hNQ4TgA-#VW@;Dr&(Qo zMM`Y2G&U=ubT`Jv>#TojF}k6t8cy+nN);`S zjq4>>MJYJVu;pvB`rtIV4q*4eX@Ls^r;NT8=!R2LKJH9m%#&gY!z-z&1-jvsR7QbrI3-oC4wFP%j$=+kS?xO1Wr}CENEj5Y9)Y_kfNLY;(VwH+H}H9s?usbmy?2>H6Aqs@ zik8PIf)e85)EX_x%h~*1;4&Jz@s_tN<*$lRB(dL)$w6LfGrGeY9-TD`#Yp0{b%T0L zu4V=SJ!l_w5-v`-Q1VB;d{YWst_ui{k(f_bxP8zx-&!p0=Hor&+w7Jm^qn_T!R4WR zJ2-jusLw>)nW+gpe}hg;bJXwuZQ&C)L&eo+%7&Jk;8|K9WxO&>8KcxD|NfsCk0+3Q zCnhGiUiiyif=(~xs&EC{uZ(`-|L|F&yU>7HqJwvz&6nulwQSyf8s7v>q5`hBHAR1I zwqAGK4gfvc4ZGBGB@}{&?$zWu+6f^;K#?9?;<$x3Vlsq_+2$F- z`&_>2m>76xTCM7o6dschuS`^wX=t(73xnu`yued3%M@XYcMeOUmGN;g@?_(^3V*ZP za``gc+>q%%k(T-IG~{)3D&EKfaP}iY2TKF?BLc^52P!D;c4Pj=TZ{hEtm)dCJ#T8c z&31=3JDAOpxsw?`uQ78+8Qu+X&bPWBkl{IHf$_F7R1w(a`=#-)2iNeU;G#O(^2s@% zu|@q!E9WNryzP(1Os~Oko#4&Z&N1?+_`EUm{tj-@O_&5AIKL-Qsm&Z>0&uM*Kp7hb z)AEGNt!T@aM8hUb5;5cSO4}N)WA&==&gyWd2 zc#bJ)M$9v#JjXFzoAJwYK6y;pf33N}IGN{|MVk}zbot3~%x^r$Oko+*nPY9$&H2?f zn>=P}1&(7r;yGqS3vz8ga;$CN7X0$O#WE(>1NwQMV+OP&=9$5jPiaejc^X*8tie&w zT|CEZ*@~PeS61q_;+N+}@|Z3z9P?bpbIhu($$4@evs7z-d8V?A$(5A}JjX23hM1>| z9mm>!<~e2(dCb&L9FGaZ+VHFGEAp7KiX8KNz;nz{PhxFTD{~w($dg~5*T`dLxN;ox z49_wB+7k1WedefV`?mb@JWL+br7FifxAPp+qa8WVDjdhG-HuO=M3_g8C;J;V|k7VKOzS&cQF@!skt0$`+?_}TJo5(!W?TG)q!7a zv&dtnmgYF-U7llxcoA#s;>dB#9$x(N%pi}MYR_@Z6FkSHI}-EE;F@Qfj{Nf6PaZS1 zD91cE^Bl90l$>WRj$_u4^2;-gJf=%Mj$_W_Ic8akn5Roaj$=Af{PLVa9y7HO$1z9o z9P>MQ%nYuzeamyqIB#NYWsN!J8Sc%mwvWkUrq<^;=1rbs_VXd<*?{Ai-F*1vd4W7; zY8{Sa>UoYy`4aPVX~J>L7QX!Q+)W-cgDamKc#c_*Cgz#JHP0$EzdVP<_~ki~WlT4YV~*fC<`?pqE?nobmpsRe=}fF`YHf~r4(ZIVwwdHH zUEDd2d6nmw!Ci=X%Ib0)vr89#d7dSYnZY&BLp;aq;782Ud0eyJmr{Y zd{=(8{f|6mHrFwq@ftcPaZS#J;yO8^Bl8i4`QBaIUL9Q#&gUR@|c+)IgY9B!LPR2civ>+YWu;JKr1Ym|K0 znxZQK5Za+d6N)YkK&ZoXH)UnzbY~&0lpN6dEW=~@T5=Pt2^M0Gw+7IEf0KO`rx|1 zN?(56KY9Su{qS9@sQa@wqV9)<3W`&zum`=7XdsLBZ!>_<{?Gd|x(NA5?b1!3zK1`q zXh5IU13LQ5|K7^GJZLGc)lVQ){g5HQL+RFjHh}5_3dK68Wc``Ytb!_TerbIzJ?-K( z<}a7&ZWOJn+c7cT=Z)FKBK@3!|wGdRY2M8+oV6hRZX1G&{3^bAjRWk<>sFDs8PSt-E z7U)Jibu!Rjj)hmgw{H0%y4(0SI~slTk|qrlNYyrE$d9VRAvU1OKZMD_I;z&A(5#}0 znnTZC(~(Y7%+zdkc7szDl`?<($D==xb3s(iI<|R}Hmx*8H#;(XOXC}k26}8l_YI>J zZ}c4pG369Ym2QxzRIM3=qv|x;%bBWB3#!1*->GVjqpHqeW_(MkLJ3qQ4Hnw}$dG6M z53xo64-uvRQE1lmzpnbvy|sg-v~GLEfhQYlQZ&##Oeyy;MEV0c7u5gjLc%)VZ~8$> zFZt$BJ}%4AK%c%$)o9r(OW!fn+Wrp}xBo-2{g3u??f<$F78fe%6U{DEx+}tm;kw^V zPU!xJ;e_s=Cuiy>wg=N13E{IV8BKMW|kaMtLuQaYeYQM*%8fBglyK&A?XF^2q@ z>KkSQrdFU(teaE5qR^~i3Jls2LRFH|8&~dH5n8P&MT3dSFC7-?r9H!$yah2;WR1t( zXMdM7(3f7_Km9!WgOvU_qeb=T%ir~Lkz2uY%C&G&nfe@#W2$llvzIGV?ok#@d0aGO z3Vt^Tj;SOxj>U}fz-(P9-^KsA2!Y)X6hgYcx55V9zYK+9UH5-Mp;^`aIk(45_tVp7 z-~E%G(!4fB>!!=E9^3a$+9T46?w`CSSKoH4r-4o?=V&PnPx&ykC@sP;-GZ^5lPS}AI) zrYUi)dIIg`dY~Q|!?Y@V`xk1}jD@IGjc?CTM3OqyZ736fMW?nj`+Rb~V|C(Cft|Vq z8S*<*u^VQCPVF*`$-%l#U5i4qqEq3~VCX&lLDSn1gqnQbW&l@EdD{mS#;~aW*Q-j08x--etEy110JEBo1dR!fRbx0fy1JS1CB z@7gmg&S6Je>Me3Bn5||SQP~RC;Mf|0_Ht$GZi2-*OXjNI&RM)Qu{f-5p`k3WT981% zs!P0ZtWuq(E%iQVN73Jn_W@Em(9wQ<>fSn7i_*ml#A+`xm=0OM1g3P9>Ey$Lo0HG4ba+x zLa`1lrz9pcE6~zqja$5L>18SXWtFztuCNXi4We6@sO~pM8j73?LTiokRZ^#$tqgQV zjq1BT6)R8CnJ&XFhqmlX{fXQPM(a_MsAxGPWw@=GyM_1p7MUz3G%HLgX?gnOAaD0*rsbx%d>3wnC(qHD!&3@B-6F;XB` zN@U27tD_@rz*Uh^Ob*s@B_CxqR{+GeX}7q)ly;pttN2>~ws6YIxLrFTOurvF7sS=F zo+T&M`_`JGAGUb9E_kVwqKmuKRDJd7Mdcv3g1Ks+A}UvdQ*d03LwmV$^=d4`75pv& zbd^QjKwQCxU`<>FM<>LFVIK^6jz+YgYyDUPUHwK2r>l=o$Agoex1;D!#uLJO9q4C) zOR64K`%rU63#97|GUP{B)iE}pD{PDybm>uOR?J$NwVXFM^aTdmP|tnbwV7X~w4tTz zGP=lnY5B2C-h${F;9ADsC$$Vk>yKYcz1FUSfgUFtSOTBFypUpTY9S#NSFIK z#*iOfBgff*E&~e1y1A>`cqTL}=+ey&dYTY*QBSAkHu6g?TO7_^6N|rZ)j_XC&IQpG zdSrKs-=FRj4eqK#_T8>Z(SzHz^&auU)367*6-?LX@uJdIc><0uFSM5{T^s+fpeybj ziLMs7#f)`mM2opA><LPw5%FuUS14H7s}AYBuXAwRlqp(I581Wolx zOb*u3HENR8bp7XE$^T2hJt>{8@cF|v*&foBv`XXIO8O6SE{Lu%H%=x;2Q)FzJ432Y zyZv7Yik^ALag#c|J>~ib6SH8tdjBCRT}gl7=vs#Ma;0ngR13OvUrBVe#L-oFGGXpg zPBk_DZ`WO#$-?O}x%~Bm;nJnsgTiUU=E(x-dWa19(bakilZ2>rrA!fnuG=UyE9Nd( zX1(gO@ivt1!eapG0+PU6OOI5ZY9$6CQ$@vK>{J{EtI=Mr7&y{|t>8)K;0#gex<3O)7nsTHFSIO`O&p(mJR57h(fXM6t3fJ zCNwMP0-=o}V+POF)0vlEX5`Fvfb|Y>y7?nUzW_NGMAzc#)Tvf=0w_A=^#O(3!y*(t zC}dBA)x*jeZXmaU>8hA2DqZbUadZtvd%4o}_dE-_(n^r%!d@VqMk89#HDR8q@qe4U zTFnto*S#H$hWh1}#VkLl<_M%~Ei&XsR}M--)KfU=TqXzW=vqG4db$!HdS6Z5rl&Kn zpGy9`tPn*5YNY-0ilO=s$hjc8_ODbwefY_jqT`0^rJJ{Xl+qKMdv=X=E@o&skBM0@ zU5WEVrEAGN99@UeUaoXyEVQ62y&Q=y>;;nBd?pSHx~458&^2$qaJoz`fBkUyidx~Y z!ohH1zCgMPEnp1!(babWlZ2>rtw5nzN7q*rnl*D50BI46?YxX-em>C7c&-q7rDm*G z`-N6wFnXb=7^E%4VQ>QN<%&Vmr3?nme%(PbR7V)VFIzL+K?+nxM8x1fTij?7frIBu zOilaSEVFEpa1P#7f3m}=##br*)p!djZ}R5cue0PITtj`?2tFSH(*N-ieA$_ z^26N!xftl<&6i1(I|B_%kz2vD%)KR|;+4AuhgYqo%wDc|&01lBS4LeTUf4^d>1arc zX~u5_0k5x1h2z!vs;p5cRRVK~)MA-Hyp+h0-!yY{nGNtNvYg4mI=tk|t;P$ad`wdu z+n}dqrN8?)oC5==Gm2>Um+@9gID128i)3B#p`vN1zwpRM7*%qNH5Tk7IdCWaos!a2K#{da=N6`D5cjpnxjy~$ z71Efz1>tqyvED)N?L8>^T?0eO;o&&q~Y+&M0>g7 z^>K{_UM>Mdys#HZ{(mxoSm3pN4FRwHe+tLTfY)&pigmMBjWtYYR^SBypeA}sj=&$%{E8cAFJSOL6nZ2SITy^q>NTQraB2;X zgDkX{D+j$cFdQ`fb&-_a7I6Syw`RIX>ZMdgVQ(V!SWBRw#0FE#{&tCUbggg-igoC> z^Lx$@J-S4SIZV418??KIp@QM_T7eWaUMGZt@#}0r!C4fFbriU-x0(Xo-wQOaO1+ZO zvLbJ_2Uk?1XwYbHzqQ?t=~Iw%L6gklId8k}yb(mv=TEN7*>Rz;fmWvsE&l-W`4%gvy_F?ZI zsr0vzb3t%9Rh_(O`}v*}o#^cDzTsLaigr77Ea>O6iiXOYn3x5_6|zZGxW;b6!L=Ig zj+0EK4F`CDP9;SVbBkkV;$mG}A$g13-#x(2PILiDY-GI{xfKl8fvuv#b#E&Uu3WU2D_muESiqGrlK>a?;wW+( z0j>+_1h}qm6AqWjrRfJ9eXr7uf7e~BPLC3C$X~ z0HBtS&oMq?Cs`g0*B$_nJT5-SYcz5$m;!yes1*F0j-$YS2eX$e1#!C>3d}x(l)Va3 zVE%}mOsN`{jJ-OFMI&0Az%|%y>e=6}j_&Ocj=@0xQ>p)@{ipwhLHnQAZq9h#$WU&l zKn%JeLw*>f?X&>~Pf;k=Vc@&VY7BG^0e_Zf{?diXx$2uuZO&OHdAd|Nsy5?wV9ss+7D0)eQ+nJN^m7(aZrApl2{LR&{ z2)PwZ*X@I%()Ilyj;I9(=}rXO_l z`Ua6G1yC_ zR5Ydq2!Y2;UHjW5QtnaVAVeJ--uGbH7gD;(^&0yYhHTT*e?Kwk8?KX3o_c{GsE{E) z5KicA0D_Z23=kp>B7mUF-Lmt}QFOd9zPAgUJbmlz(Id#YplQa*x%ruitv^ZWX0FHA zpO&~$bnEQgQ0IYj^goeX!F*B2n9_;FSNJg;Uw@#zT>1KN(t@wdg=D_47fIP@ObfoY zo+R)!_Cq?D!#7P`qPtjhke0@2?@MZSm zVel8?3%+<5KKgr)>a%>a-XToJXNq z2LarS&*}gGnwV}}OT22Gu>yj@n_k$jTD?b4AD?sk^ZJ2x47B|=7tNjhGo<0jtzZb& zoe>p+vuAJ+yhMAsLeTp>1A*BiKrTBG1n?0c<5wE6z0kPVSpo*7&J!>=c9zjc$P0~o zcxw)CxYnDZ2acJMd*`N_qJRG5Q)Xb|6Y1Bp0^#!bn=#}E*QCE~0M~gGiglMV_0BP& zSpiq)pSfeZJuhLPi+;}?d$|Yv2DYVzbbpO~qaTZ$3z}gDIK3NFWOgHpUe&~}efc8C z^>qKEvp04cP|sjMZUw_t=)9 zu#PL;MXR}DlxyTgXXWNTIMR{1G6Dd!JaQ8`7sOTa=z~pVSD3s7vDM?|Gs(hnttfiYw24hi z*L5?{or_gF`e;d@L5ti9W^3;iQQ5kE1;^HRw3jPeVb>Y98va_4XYRH`ut1{il*HH7ghM@Zz=s$c4*ZiAS;}!ZXt45bag$;DpGf8No3w)r+smu71o6k#MBIknedgtsQm)ZqV z^wb5Ll^+WgrRdJ3Hs$`X^D#8K#l$QaFV!tk@tSiBhu3bjmn&Y9dlq|%Mf+l1Nc&RqgtGj0pV>$Oit^K&zBPZXWHEfBA7$dDgivO7!?qT;piju?1-K%rSP zdqrQ8gn!tmr$ZZb37vS&_(Tx^y3wv3yWVB;7KE4N@VSk_j-Cmy$HE}Phsi>aw{0GMh`^AtH%Qz zUK+HQD_)cTwZO|zjyQW^pDDVFhP1%T`(FZHT{DH_WperJhkHne;EihR1#MHCDt?l)EBpidr?$`R2 zoApzVzW62PFn#sij$6;qR-mRm5{Q8T8S=xR++!PHFz~S$80<%(S%bmjb*oysztYo- z_tyZom%)#uzjqze`mRA=>Isv#pjk%Y8ZaU~t}8_+%xeBKdWtJWHw*}L^BV1CkRi8% z>6-gQRJ!&&!O?XK?d3|B?{f>fvOUl&V?h`85{Y`s#9=|#k1PUR+n)-j>%iq^(Wxrj zXVSBt3Z$$0Gsch~UGdLsK-U2jiglAr`79{`%k?>quGVNTSGxXu zWkFY3VG>=~E2NcZL<_nGz9P`&{6aWgV2(!R8wu8|GF#tP|r`q`+ap|b{<79hTS_BxN83! zB#CA)^Qm;OsbN^ZuV$Z|{gnIhRHBoEVQaQP5FQ~zejs?hvjGTW z-iZOiT@;!%AUu$snEdLQls>!t^u__B;ERpJ{G`Qd9@95}&*Uv=nwfSWY0Ap-T_{=_ zzG?0r`_dFW@%p+w2gkKG#3Q$Yr5MSrs3OA7n%)24M&YVge=OX8V_-cJ~owA9=*wYVK0+Tp)oB^i3OFLR7w1 zqEM{k>l+Hqn)wR=-Gg{1;}^gf29{>#FG=$M`W@-;-AWL~d>0jjKfmKZIEnUh1;GQ@ zfx-ZoKW>*^0)de4c_8vvWH$am;NV5BscC<^PFns$I0t2iE*YkIZvGXScTPDiypmAW zaQ%ls4vPO2!a?Xy8*s25g<>5Cg>#wEtl&UWp={>O%|$5MvxIBrHRD%gj@<|vPWoFq z067;l&(v@^aXrw!4Mj&?=ya~^KcA%Z>I*H;x&7>5SccpRo@egoii#KPX*&QwApn45 zP_#TksfzOLUmNY^ir4JI7I?*F;hqOF;)T6Tnt_J2IF0i!4C7?LF@qheb zghP=bziCEq$0Q-@G-F?g$-z3j!U{2=S%DYu@csJu`V=XxdlC#1nD590;A^2;9SYO>E2BDb_QGBzy+lJ=;I+|#fY*Q`!ttumr*UUxv2vIulz+2V?GeQ}oGQqup1g zywuYTs$SiGAgmD8AGsBb*D?oD@jB{&!|Ng1%N4IrP8N8jh0ek}EN+~=uop>P9hpEZ z@Je?g;B~-JI9{gd(DZ|jF4n2+<=)W_)O$yPc-1S)81lnwbWt1NbpnNA-RvcCVnVY9 zF91MP@#n@@cu8IlW}bvd^OzCkB}dK$bFjuqR1Qu%;W&7X_HyN*x3dKYvXeLtf};~+ z!?17g>Q#)uK`Cbf2giyD=V0}=YGqWf+EMfup&mxv-bIUVx&(&8*x9Grvmd%<+yo*|&GnvB)68R(gs2xu4N5UNScli-QdZ;T zSuF*GIbM{~)E1YtgtEoayNk5Xj{FZf7lc>wvm3^YJkWxo#}8cDDWSh3Mc3)7-ZSn| z2dah(6SH8vHbmLnaUN5?*r$P90sjC*< zs&%>l#mmc;$y*R!5#z^YKgwxkpt~JBG}C2tBLjUVrIW|hdkqX@kXylc8C*rh>yaxC zFNda&y(5^I9p`1Xx z0+As79>+n+3j8=osmyQyv$79VM<`+fz#_y!Mbjg91-tL(Pf;N$86V`H`@tq76uRk3zAIgdUZ|Ai=ny z15V!SyZ~5_oC}(0Cf(J|`;mT9N{=qt;?9|j_jvw_eb&1q7qK+Engw9G2P}YLFO=?}K`j7VRE+?be-+_?T`~cd@;hMTs|W;aKQiP8m~&Md z02Wl0$-z3n(otyEO*Q6#F>g9HZjRNMyafUFmWU}o>jOIISm^4^!n@~Y$3)tM+P*jgbWur;N+ zKnji`Lw*#v*02Eu{cDIp!Cn-a)f5!9eAV$0XNeUQG`#BBa@e>;iq4r*?OCLuu7RH7 z-M7Psv58c7&aBur= zTa$o5H#Y(T8*4J!2zkx%_hH9gPjxSAp#NPMpx?LXfSxYieZ!;O10$)2H3foIp%!Dv z53HD4HUMiU3dOqVrBrPuG%LVrUAlMBgyGdGI&E?9v}tE68R+y`i?9B4$$XDkpzXyW0a~Wi~oi*T@ZXu z$GahYAq+m4k}ajd5cI=k_;?%0mVQT01=HHmO;lRtZa7*eqP<*c&8o}LTL0Hom*g)* zD=Yw{mB8u~G?c}3wYn~W)nIqwtp43O-h1)X;s$g}D&R2PdS=V9Z9*SPXSxey^#n5H z$7;noHehvd9VQ3sSUrS7vw~HiTeVUe<}an6z3skRk=BW#L5Tf|Sv|)|%hYA^7R2iK zz2IYG@2&>gZ+-=B&9`ZKx^`84&fpV;s37E4Fjfodii*|#x;U)vqP<+Pq8c(-nZ1(S zB@JN(eL$=_tJPZE9OzY#Fb95ZK;UXiJ>gt^tI+XMpP~K~J?#6|U|;_)Qrc&7)0*my z%MU-PCy=Wu^%+BcT*cM50atrbDAsZ1+JFho8m_1v>UzD#O6ga-_qJ>m4!O#@Vi>f2 zt#l}IE{Lmyn%~#-Nc5rTa(`TCxAkm!iax7pvv9Y6ZNp~dRxnqu8;Hu4OG6x2Ezn-B zTrF$DaAo#oG6oIe%JgM2!D@w%JYIoAYcU$mV#?~>gn*V~BjIS(T61X4s78Ji?RB_p zRr}2Qdb+lEm7$f_ryQml2}COq8S+ExJW4{;`%tADGdWm?ma4J!Xn{2E-rsK>rRP8B z`0`+x`o@Lw7X#~EK6(l{7lc-Ft4dpk*`Mxcy3Ju)egwdw2@|tmwEUWgiq^0uIJ9P= zypG_@Y7|fWlaU5bp;vnL#vJllZ2>f#dwH;*54>JYi2Fumd$+E=3xhBpaCr?2yIEA zpj&f+{W=aA^6S?d&27-HRa=PBugNW#(5&v)yhC+MI29z_STHA}V+L|AXe!tj9$9{O zN1&&h`uJ{a6`x4al}jzHwsV7>zI00~F$iiYDh7!yaTqK?d%0rJ+mped(XT~;j8O=K z(xzLn#5KGhXfz83N_i3(h-t-CQOFwJAn!3NRFbj=df@AFCx2c$Af+o`h~5%BFw(HD zl|ZuYB13*;d9=0xS&6O1AnPg$%?h$q>$0o=8&};xhbCN=hr%_y?BkEC?Q+i1H)zA; zEr_hQgAcY|I>;&~6g>gX#oR+pPF?xDU{TY<1nL5BQby^oR*^|Y;aJ27C@wPWgQ1*`y2)9&xO z-jRM){?^Nw)o`%^faUA#?sdG0oC|`r+KQ}FZTtrr=zGVf?BD*r2}Rd>cy?60+kg6s z?U|Sbb2Xs7s9cS1kK-y0?d8gqgOuUQ>`qqZM8s9zcQlb!@d|ffLa+eK(2)R^rh{;> zj^ws0W?aQvKj7t?L(jkH^R8MqcMu5HLuAMgtkzyk5~6~Y;w1)Hw^3-;fEAgvKyoxy zPj@UDKKEdM2v)^jO8y#_A<)FP>!3y(Xz%qMKB6}tREAK%GmSwylQUY65eF$t_k_u-F47{c_ zF5}T-&mDg9;J%cm!WJvxGM*zPkS#A{$d9eLlnvOrg+j4z8LyQ$6Ph(_fy|YyBd;B$ zQ;SVxBc6x#Qh!V;$90|R==n_N;fGrk*=y6*YP59E10cP zKBBVK+y}>2Z?u;yTctZ$vQ>RH^O;+7wn*!EhtPNy^VWHqz?QSGKni@3AwLQh``Unl z|DjN`2@*#D3rzlQbiY=efK-I>Y3x`us)LbK|y z4T{e_cg1v@#JJ=(eP-upmpb}(Ve%Gq*p9pT;dA5IogL}jxw)$XX1h`Ji+iCzQswC# zCnC3kIXK-#R1ThZ!EsQ+j~@rq{TUAG002sQtCX?E7vltJ<>A8u(m#xy^TiGTO_JzH$z-=i#5P(r_`Rmm*T3QK-Td z+=d^HJeY}X=7B>9vYQzr!{$0_`2#%dKT9 zF3sA>jLSO_Df!$PRSAk#YqUmBLC}$R|9r9jwhigVgx;DEx=RTZdTjtej5>UnzbY~& z0gBjHp^S>w#^W;R)s2urr*8S00=^_JA_eEw_&z9~y!SyF^MJ<^maTFCy9kCCh$K!T zI0q0?00H8Q@ECccLA#5A4pIUIc?Wsrq3umuT6P$s17 z1nMy#64Lt+L|D^Dd=V!1Wfy^ZCxC>JeF+)F_O%@eKK}DyNsxTvBZ71wA%*4x#TTJ`2)hXBK)@BVQwSl0?6=DMF@Q*K!m+Yf(U;pZ70H* zq3k52{*Mm{!-o=5h!`q934X)aMF0;4h|qo*A%iBvY$rnD7n>uOV1&CmXA&9Um#&#l1iDef-c9#zcqhbjusA9z@p_huCgt#99MChalMtz8Cn5c*022CZ2^j=vZ6`v_1a=W5&-u&= zWfKS~I3|cM!b=o7iG*xZ=zQjc|B*7df->^N7K8K?vi3Aa5B#JLW+z56O zLK~yd`G^ocf{;O<5w;_tVG_FtX&e?B78)llSq)Y79c_vDTBKx16z=g zp3E+SM|(aZtVt$_urOJC5k`(=CjrzFAVTa&LI$BDZAU_@QS2fZJo$)FZxkVgDx<^~ zAs2;CA|a!L01@7kGI)YAumuSRQwk8FAs-R8rVvC(OA%j$iKE#`(A5(l!idp?42F)j z9SPDg>>|W<Q+dWT4gAjs*X4>?CBi;3GnZafB3_juT%5*YWHk=voO7!C^ch zgB+BBEl9Y8G9i(W-GGk>$4Dvc9xuKKizl#)KvfhV!t@CQ5ynig9SK1b*-1!m$w!3F z6A3A_ohZHt)h4lvkSXNTn=X?G85EvmI}vW7Oo${@<0Ha(QVK^=3Sutct^R{u1W6kK zBrN!YAi|VCY$w8?$?PP=x$zM}Hkpuu?_}{ws5^ySgw#d?M5sK4kb(0Q+llZm%7jEh zW*t5vTqmV)7NsC230tPJi;yjZgjG`sBFvp?I}xI$v6CRH%149&(+DX9P7|MmX4Bb4 z@Te((1h?sg3@S{wod~Z`CL|IlcRnIKAf@mRN?EXl@DU+mCLx8sGsP#N{VaA7GRg@cp~);l1~q5dPJ~Y=6A}q7yyk@Gq!jL<6vQOK zFq>V3)V2ad*fpCV!ur{^6Jb@PzJWR zsk3G|y9lXe_>i!0IYES}%f%NVb_F{L>6HbD5W0epLC^}@kx*|Xy9lAKd_<_Sl8{2l zmEw!=9)(UK!K17I5uT7TxP>yX1qoYMv5SydiH`_rs|X^@TP3~-BhuJO$Pn`I*U&UV z27}UUM?&*I*+l@RRWMF-g8QF@6e|8Hz6jq@=p+&h)di67mXyK2C<9xNux~ZH2rj%x z*tD7;!iv@6i!g2tI|&lgomoDosMMz@oAlt-FLPj4xBKU41q|kbk_##x^%q~J`umBO9Hxn`d zn{6k;b(9H-1euJF2xmzt96~9Gxq!E73%dxZK>|dWyM-Xaq%F1+VZc^)5?liLh!D7y zkOH+;d=lKYv5Syt3Z2g>YK3it42o^Dod^$5CL|K5NIoL`LrUQkN%3XD0!K^AVwMIw6Iw>Ee^nWCyzlh9Lq(sJVlXLD?O)6X7|^ghT@H z=Oe;BQVN$*3SyG5YbU!1p>hEttlvoxVaZP0iJ;oWPC};XJde}bk$e{+h2UM{li<0V zU4(2QhogqO2^m!1Z95S@piD?4q($%{;VCJF+b9JwNjS2HU4+ms0!T>TLl9xj9@~kK zw3nR(k1#$W4BJacVenq@N$}anE`n^R01;a4BV~~Jgn)wuh~O>{Lf@`X2i!_Bb3BuK6 z%TYp2S{>zC6R6%$oDr!eObXf3RX8KIny~lDMLl~>Tn3ocq!+Fx20fuB{(2rYIW#=C zM#+b*sWCVsQcWrW5Za+d6KWUEh*Xo(0E9YBccaLCGSk4$KGmNy`#J-mIPnJCvH#~W zc1?9YW}0HzpMQ)HcC}+XGzB1TerbIzeJ`95NmCcEF@L#CccUibj7Xa5>UK5#7pJ1;EFx?-4 z$3raphffe{(&+?`nmpX@Hz4$MD{3Uph*XpNS@X+%?(S~bjx!?FWZKo#frqoo8*tTN zwy7uC*_RCC%znyALUGh5ZO8tKQ|y}RdYJV&mi^RIgs>}};-M)3)Es*DnvUIZMkGzs z6f-qjo!zJjI3tp#08lCOw|_iJ)^x{d_L_vM%xZ#Vf9+{PO&Xu(RTH>nOT%zRq?#~k zWlI;~jL0=%Mq-R{+o?0`HAxLMs|l9<{bvX@@jk<&CbN!h-lR<{O(o)tNHuA8WcZfG zHyjO{aYm$?j7{jiVYK3n9#;)!n{<|){kVRd*-tu4D9*66wqt+E-|U*|Ld-P9vOnW* zLfGa0=AkLjRsXrScCfT7&WNO`ZhORmCmU;0V{t|#O@Z!VO1Xz2EPcN99D7Y9v{_BC z?5CY0)TI77J~c6J+0wx{BT`LFM)Pn+#G0Uyn16BGvGeRT$t>`kfA@JpO}x(YsL8sJ zu+I0JevoQ#Mx>f7`Q}hQF3Zud0cS+2$?3~fjh4N#SlAzTft~#f(|y5$ulKbV2*ruI zU_15~Tx8cYPGQ#PSoWt}B!pf1A`eXg7_=jVswC}TzYl?^z-Zw(lt0EQcXV2Xi+`- z@^=>YM`y6JpUwT8KQ4n%obU|Wu|MYuyQZnJW}0HzpLm53w(}JpngWn>d(3n{y${Za zr0Lmr|D>lhuT71>8Id&AO_yIiw(lKFpRfCey(Sr^M+}H-eT)Ag)THJ=ylMisY-t~y z5ve8&xY^R_I3rR`Oh(MVxb47I_L_L8&H4n({+6qRnzXvgqb8HrPl2R&WNNb9O=l#S}dCWd4s(s*#(~S z&%Z&aNwph1YQiv>E$xLfVyg)}U`)mtk!oTZ2}eD%?YYTb6GNwh*xz`QP?KgidDjGh zNSqOSO#oPiGh(j^+m>*Po&C6OoY{}QMJUd|Tef3=>TPySsQ@!gvGab)Z9>@gw|Qzh zc1=mD9nOeF)64*MB}$DmV$-zDB{ud~++nXtwibOw3US^~y+f!;r8_)p0x|B6Gh(TU z(P#qBh^;1YByy+kxLZI?W|`FlJMXW(OQ=cXyS!@xKp4)5y(R!G!WpsGgl!vskDdM0 z38*Fo&-)Sg2*v4p&vxujy3eku$0RdNvFs<^CxmTxpSPx2hg;)}*fec(qZu^}XT+{) z_5rf0Oa8}Rlk~-AHNjr*&-fpqCguLeyC&Jvt~evMnm~-l;*1KY2@CsMAF$UX?N76s zVA)T5K&VOm2fS+nz+jvadrbhChcjZY3ELK%$<97Cl{5RHnS|m5W!jGYaSz!wm6#vT zvFvLf62kt0!shgBkHg0sPP<=}pqf9#Gy+M}q$_R41DP8Yg)<^)s+&;q(%bQD_ih&a z%U%t&1`q?-mQcZU485ZZTqbe1ANmejtzcQdo%58vCb}hNHNmn!@hPDu&QCGv6~w*|&WKbK6UHNO zM&z2njcwjv_pE@Lj5VtXmi@)g2sNqsj7Lpo*zfvkXxf45gEJ!4qg?p6r$A0p2c1;bl%{0ZbAM>0L_D2*pC-!w& z;}-8*dRf}wIi?XvntoZOt+p$y12qI^MA8&Qw=PlLZw|{GH}eI1O+d0)O|b0iUJz>H z^a7J!LF{+L8IfvYVm}^dM65}H?Em?ay(S(>W;MaGKmR46Ce>c@sL2}TtE5ghTN!%c zj7T-fs8M~_r()%)$v7iYO)_1ET@G#8mxX=#D|Ytdrf_CI_!XfzU0&Ia{e;)-nx>|j zX^Le(`ZXc!cPMO5>;n+nrrqNH(mJm(jX=`Wb>^(%YyI0&193(qO##TbT{|I+W!|6q zhP@`)%gkzmWk2N&p(gfkFzFS#!Cd+!3oK){yYpOfWh*Xn@EuO9mUMi&~;EYH$Deh8J_0^{r3;Tnz+1Z!PIv{2jZd)Ecus$Fd*sju7^16gDUJGiy0-Zs-dPwccSGfuyOSp8L3KGrvmv z;*3a|8d|z8ql>&}nfE8XXRnFNTCe-x_B`s)>pHVK^gFO-x42 zzqoD52lkqTjxehUmi-wY2sJ79fk#aSxR$Z^Ni9Ql#Tk)mqCb8u^;)|QhOsy!QcZ?V z&KXzkOjnlY`TPIJ&VJ||&g=*LM<|Z;Kijb%`;lE!*-|r2vFwL_B!vAOh0Te5-Rz*J z2~ijI)jwhyfuw0#ZX>_cvc;(&oDoS=045fH->L)4yg%*}drc$-&imR=gqr-oMOqO1 z%|G#|i3#H}I{K1)hzb}O1wEto|_LVv8nx+po(-g~o zNDd+FCn#)A?EmLp$^T2hJ!$0}Oe2sqO;`B*;hJnu^}rdCGzB1OmBzCb%N#fQD|<~c zpYx5qCOVB-O|a}w{6?sW^EXU- zq?(MmaWXkNpozf;XGH3gogr1H-TtoxH3DZus>#edj+@l!?OD$GdwyqU-(wYL_UZ40 z;b~95lET>0CX1~1F9R&h@>e1 zKoWRs=@AAJ+?M>4y(Yl4eoK6|C*~)iCLeK;lKPy9EnC{)C%>8)r|=;-BbJ&JFz?UI zWv_`L!K_cP?CWv~HF3(tq{m(p06OA~So*}c#p8_FYr?h#f{Fmn z-bf{68g-mPqg5*6+jz79g@8Q(rk4kc`tA<79TPw4-5nlt%{0ZbA8bbm`#uVr6Z;;X zKd&|2Uc^wwj>$Ej5lPdu^*MKDmaR&4!5I-XjkXJY(C%-Rc|V~LdreYTnAHS3??)FR z)Z`s5QuaR2mewi6qb5uXWlIO*jEFTcZfxiLQwy`#B*XmP2bTSm!i1XG7sjMVs>z)N z)RCHN0;zU5BT}F2@?IX^^R~pG#u<@nQnk}N??KPHvz+t$7hz{VHIXy>9f}Z&)3k`~ z*dJuiu4&pxvp&bNFS93veH(?H4`Y(1Ahc0r%;35DlJ=NJAZeO;>19UFYzN90XGGEz zfDosfKVn#}_lG+aP?O1KHNmnU;XtU#Yh0wnnjj);Iq;~7$*3>Rh+Gr6v9UkNk-a8y zqs(f8Wk1Q0P!l^xOnRi6EUr$SYE>tIYK=1@^-0R>0}8i?MW|soBT`KUh3sjtdRRFY z_B$12XP;WgnSIZqgyJ+TYCHD(JF#mj)0t_CWk0})5cYKxHaGSYA9`O+-KH<*glPnl zrkU4IC4XL4h?3%rNSXp_r2X=Wp)Bmj7GtkTW`WQ3g%%^!2*Qq7C=s7c&#y>#=okJ2cd z5ve8YF~v{(9G{;vA?zzCY;NoW zkQTAn&db4>ho-P&pAWR7+T)B!ngRequhfk7V)`AoDNC}~Bz=ropJV6!kdlO&Ji$du z>T@QxY-#0^JZl1{@E$lLmYNhW?~g9UUXyIowJq!uEc1f1!qLA3EbGu`4cLz*CfOIc!*^`x&oml?{JZl zYVu>q-nP5G$f!CMc+_P5rwcp6;+?61I3rR`60Zb$c8{pQ!hWlY?Cht_=gfY+iiF}+ zsc1X){VTC+8n?i#&#~A09V!vRK83>O#J(1r%9(bZ%j)X(db} zkTeBxUyGdU(~o7|A5@vWCNj7RV5UsLRH(b->DkArrD8Znqt}atVRg?7z&#c z`v3rHqNn7@C!7&WpQrg1x2GCb!!!a(QviU$|4=B){r&#c*=v%TU{(_>`vKJnHMx$9 zl+@=YB8yeWq{mVd;}kB%8L`x)fO$W*2767ib!IievL9N5P?P7lNZD%wK=m5DYXU$J z&WODxY+GXqJNsY~XZ9r$LUCLrwqxJBCcCC-F=m=#*>72s5cUxiHYfIVe=pFyD)mbG z9%n@Ab6JtM+Jh^qQFUu#8iA;3qrLssc4NEV?_G<%CWcvNHNmp)SBp@SE4WD6`#f9f zPz#eDsU}RbW=q@SjEFTcZfx_uvNn57GSy}^!LlDxn^2P{xJXGgSv==$*PSioDr$dUAC-muynW`RoflY2qaB`&OYq@BNfXzf6qGX zHIbN~3t`!(>kw*k5f>?`&rL)Ys)I?7R1=d?8=MibCIzyusLNiHv}ChB!Lr}4E}hrX@%6t6=6{2d? z$20;-Q=ro|XdM;8!hT=__L`*qVb+kL1XRi+^(JyK1kzr7w@3;?PN&WO|}B~EN@ zyKqt|7WQj4VrQS4!kPWDjR?hYY-Bt3TQz3aRMNHE{JeE7?7UyEF(K?7C~R)*13)bw zpL6&r&WNNbd^CS~aAB%SV@xBEG=)Zwiw|PCzwh6Ky(R{QSxvC)cW6SW$thfb74Lo5V8}%My*>w5MmV;vudnx8w7^ZJse~!D_ZzifEPD?u+oIkNd#lIhcURcT zztD*v{dS)+GRdH=6n~x< zYyP1Xu`)3{UyC&^pYmk#YQtXdf7KGt#MPI`gxdQ(S~4=ZNLwi@lTW{#G~k1KU&@tR zQXU>Flil&zD?=ipG#XkF>v{6$>`Cn(&gp_&_v^I6d%t+1#l2sp6(gLNu;f;Tf6%s6 z|1MAS*0^cGIKq_L`_8Qy%ih_F!oxC^PW0}+|BG17&$J?zsl0G-OxJ7WWXIN&GqFr1 zDfDiw4cPDN)3(7garlPFgxdS9+AuOXMq4Q}6X?i?v?5j}#-b)|xH8diSnv03i)WJX zC6NiW_q(-aWOA0aQdTB&9tZY+an476t1ac>u`+pk>4@VUyE)2kv?A8?B(C+GlI$zk z&-ZJ#!+Sq(jK#fQu^l6v5?J!<==~4dkwnVhDrl$FWyN%fCN2YuvnZj^_|%4FR~ zR|^(ge@AXhD`GuQ_Ef8KBfi8Dx$al*i1&U_Z;N}sd`Ct&PhiQfqxTzkQZe-*OsTzJ zyAxyCn>$i?Sf=`)x+nMlx#J~T5zAEnB;C69g~q-Uztf7aO!SxV_uct2QMvB-)Zm%q4I-W=)ZUjhj7)x{trX8h zlK!O?;h9KMOAU7>*j81>dtWkUqW*eck{RJVf+fF>-mkC4O@jgnQ)=(m&@z_&y-Z1( zZ5sA+_kn9^=V(Q^X#=@}mU1Sf_mBT@ zcW6a;CdC>j557!PdcV6To{2o2$b{Pa9X%PDWYbp4%A``&PjkL)^N;4gv?5j}EgUnq z|KQw6{=}0blQzXK{i^ydM}8husWaaDVG|$|_1=HZ3g<6a^6TjRdS1Ax&YLi$_P&D` z!*pF|O42M-Ns?am{ux>k%hd2q`BT}}i*hFGd%r~&JQKMOkqNc;8+Bo1vWK=(B$HPi z`3tQG&!kvWs|#NyD!uR370;wsKOz%q@3-s9$RvZdQdTC9*Y64%cJwXzA6gMBlNX=g z3astiN_OeWkx7_m?~d(bP9d*@?7HE-uNz=-?>}XQQv^$X9lc+tJ8oJ)zOO~?{VLrV zrcvD}NwZ81Z7dx-Nh@NR8j3!aU($+@-q+vuBlrBxKf^O|?oT|=slD&~86%UO-MKR< z*8EH>!ZRt>IDSSs6P^k7UZ2(*&qOl5uf_a3ysf+$nH;07l=VCrvg>!dOwZ7FB-`uv?Av7e0{mFowKojlk3CJ z@l2eJKfBRC&#Ap%_j5)ju{}95F??$))?A|%u`)3hRr{QBCT1qDHmvtMeSv49n?yWM zsMmehFBq8|p{1nhgmZ`1O?C8Vc9py)~BIfhFqI;Kg$IZyST>XA{Ch|}s6Ke0*=*P(9`@TGx zz}5I1t%#M0v8X~n%9)s%z?lsHrERVI7)e$)PpO!m`O%6guBarv(E>hRX` z9a<49lQrLc`$_dCjdV`^IWp-|xn5e~I_!6MJcdkIy&u-i;@-c<3MU_y{5pES(pR`? zaE0SoD%s#LVQ?hTZcw zABtzvYdDb!wfCKeGBVjYgd>v&Rp0X0*z}ZtrWLU=SripN=5e`-vg1(7nOK>0skZCo z3mXsQ_5L4_39I)bdsy821*~w+!;)V|@7ws}rqUOLDfPPlw;#iFrXM9~R_{xr&o~c% z6qkO0R>U&(`>3nmw-?IEcWFf|Q~lFCY^I~T;rUM6Y7WCQ$s;qN_I|}-j7*mM^JMaB zE7tr#D`I70EGnTDVVU69{SSxZnG}7A0U zc9t*EiddNpt2F9*NxO&X_5qYLu`=1wbcBC;qAk+Z&@4Jq+xc9HH!pVgtzmDF2 zHX1jL=|w!xsn`AcqZy{bqbW%sg zr1z_Sjc4K)Kx9Jged%jPCX2@KW%8;c(`ZFVCa;Pf(Tb2vRC>RDAfAZ>`Ppx3@7D-q zWb*yj+?hzyIa(2(i6m7Bq?`%Q1lw*wCam6fF#bI__0RQPV1<(dOMV@_|9C8J>Kscv z&#AqCZ!E)f;#f-3%-;Vsc2ldy_tUr2idd#=li!!FM%R<`X+=!ahmNz_aH%&Sdy6ZL2o{&%|K?kqNc;9VRd` zSvQ^|laY=+rX>V@CZC}du`&r>`su%;7dpze6DVh5W#ZDKXQNItJ0Y+4Z$Kuj-p`AK zOw@Znj}=Z9Ectcx{(~UgG;B3tO6~n$gBYgcf+$Hddp|7P?jw&S>04+;EK|SVeZpFg zvym^;idd%lXLiOUXXN$1-6TAdV)FYTwfCP+WMmRPktdT^Te0Rat%#M0v8aevgk^%? z^VgY-XCluho+s4auQHjDNz^2cOl&56(`4KB-ttLW5i65kANVb~kx^0il2*jZoLME)A-UGd0G+6RNow7PoE(7{5DhZOcJ7qOsKv8cQ7N9nZZ1nK<^)* z6|pig7Tu*4VVU5)UvrvDCJTv7sJ<8Y7eCQ#mrJGUdE3T{xf(?Z)&m@+`p??O)FxVp4j(8 z+`!QH_t&$KiM;kzqt8)ZV`r&d6k9I8P?8 zwqnh8S`jM~V^Kb>2+IV&?pK8<4I$UXm$kO`~zBX?Nb`>Aso;q06H`g;Gyx45Z;@%;+s z@956^ma*)wzU45L20O~mzaCFtN-JWSI=HqjsJhHn&Y~5uO!dv7dx`yg|G_*wle}HT z^PJlIzs_T1GHxDECeZs^Xhp0{j767eMOY?y@7pcFGwHR4$b{PaPv;2`;*$>l;Xhp0{I(M1^c}5;WvcID-|BX9I<1Ihs(+JU`p*N9 zzsL8-B0Q6zO++Tt-Y;0h$YjhSzD!hchQPinGAZT@LYaRd)-Z15i65gUySR&$shaq{*je< z?>o=3xc7IjWQ4P6lc{{C$mC5mgGaGN5QIwufD`I8xQQhuOW#8# z>b<`$ni0;L=-1c#*&A?EIfgK$UiXtXFqW;|z+vhCyJF3Ev?69EueM@MI<1J6 ziLuD=U)uJ^Mm!V0r9>vw-Y?k5$Yjh$j!fb@h8GmQ+fuiYR>aDr{_XNN7S#Ggcb-U6uS-I);^?pVSZtA*>Fs1hXp%})pJH>FAwyQTo z8dl-7W)iK4Wh(D>hzYJ?FYllgu}oh*v!~oe-siu#8P6nWH<1ao_fKqQWYT*xM<#|I zEY{4Y6|pig7NyXN&`i+x`hMG@lF14p6Kd~Y-@?db`&~N_05r%@_JekE0a0C z8@+PAClef}}Sf={saJcalx#vF{i)RwHmB@tJ z`^RG$ne>e1$i&#jb7)1(OkQopnj~5gmI>bbx3}Y&^x8&bLhb!4+ZmboZ|BHl#GLTr z!e^~@t7%27OuUb#EOD6GOqWY5Vr7yu!^?Hi^^cJ2e(Vms_x<7^6ZL!kwL2K$MC^Ed zy?-PQHo^Wm{okth`sAHXU(3ewnMl$KS`nU!B<0YG@Jz66b3ESrG2dF;`>Wy^;Vg)MeZ8N!8#k4Y5~kGNkK4^y zc8lFsn2w?q;ie7bXj+l=ra$h%GwGE^WJ2xz)IE$$y!LQsQmpxgR)l9#tl38^!ZX2s zzJFsco{4ihkqNc;^Y$__`D!mmCiC*cR=!9$u31VeVr4S(?UvVa@*bvV(TZ4^eEi3Q zo^D}Nk$e8{_o?)Lw#B_4xsMUf+P zB@vlWd;in{Mkaj^aAfl0#F%?0_gv6?M=N4wGPTL~r?2Ie)1}jjSeabS)!C0hdw<H1;eem`5{+>g)X|Mf+DYf@w4l$Pf;UNxFLnl@|HiTBhGBp%^EU%;$ zu}lp`&d5D~Mk1a`&=DdNYVRLPWMtAQkvo%O%_Le8o=LH02dxOt1nd2ahw)4bE)tng zd;i2?Mkc)vb7bOjzFn)p@Tu~AS`jOgXAA4y9i?lcOQ999GFhnY-|^9G?7AP7g!g_- zvcFo_XPXwvKJ{hi6Usozh8DYf@EBr}%XIGMw=P4&J$b0@wh52O{bOk>vejrs0G z9o;fo5z91T>Du%EIy^&uXVdFL?+bUKYo;vNzbDknZ#b%6!Tf4R-QvEVrA0#SlpNI zeRWThL@Q!ta?yXh-Hefsk>|vR_PeposqoXP30ulG0W zaMPG`#Pgim`>S+}W!KYjm`d{g2~GRV*7Ttju}tqDI^3%Da4&fQt%zkR-8-uryl)%w zJWtHPGtnI+GNJZ#R{m`YNNw(s*RX`j=ISf;CPx)&XN z=R>uz<{4$A5sJ);310xgd4;-0HZ(V0kpxqDdQ)xwbCXy6SE5b9uws|>t z?-v-qAFBU+KO~0{PGHXK>-}{naMNB_2vchBFFwIocFhwUrtp;Q_!+GTGfjP~fjpa5 zgqViiySgcrt-9w&Jd>~lA`@!w$Nb31LMmjU-uqK>8Q}!vzP{d%I)$5t z9V1Msy}$4jW7*YDSz+3RR)m|jl0#`lY}1fSQOom?zr(xpG@eNw`8=og{)W?xOd6l& z&ZJl~kXD3eQmk1aEW z6A#b0)|02oTWLkCO#V}CeZ2!aY>@Z*X8wftet|I)_1+Kqi4o55pI%?@FVDkG&vv?*6 zKN6Wxdw=a&Mke*oa%A!oywBf{R>aEW_7KDS{1LPwRwhNN@ADryhiBq^fXIZ}`@7FE zGHHE|Ba^>|9Bs4Sw~zcat%#M$lr@L{8a=axyopxC$|U{XE|LVJ9II z_1+(Qo)ON_^RKV>mt4S2d*u?Q)ZP!fz*u&r3mm4BB!73~;6-U%OuQ+_g(XYJZ3A7@XsZ_hq$MiVj@1%a+ACb=pr+@zI>-~AxanoY*UXFU* z54p}*w#{`8Q%Ne=*k;s)v^KONmT6?=d2i|8=MSV6u}mc?ta;-T*~oQ&-3>gGgiC6@ zzxW0tlbScUGSP3vn$KuOtV|4zTdbK)D`ID2IFq56w(a>D&&2OKkqNc;V}532^5M@M znba&v-X~8@b{|43Vr63AX?3gjPKTwfq!qC;`MBD*o$H2$BhQm@H}T$=FF+>hz3+FE z5suHz*Vp^u1-NPPRl=0o`%?-S%YFgNZX!vNO)nq)OUe=Ke~<6gR*?E>0p*FnGS&Y( zyuoSCasaJ}WokH681g=U)Ga)d$U{UX)a(AjTZ~Mq-=aJ`=D$(+YAe=sp%o#Sy!wU_ zN-M%M!9Lfw^A|jmu**ay)ZX9l3nP=pzi?+FNdsv`cqWpxj8=qaf^B08@!oef_Kte* z4=QAY^F`t7>;0L(;-;=Q2vchB2mQ)e_A^+vrM+*z;^bNPkAI~+5pdI1@^D%a+caWH zm%C?>@8`>JMR+E~nrXBmb|!{z80=?y>>WH4hj)nQ z3AOjv-eF`?{|-kcL6;vrX+G|Ndp}wcE0aSnUvBELtdSf+D`I8x`*pt;k^TwD^Caq? zA(QtcNqSp5e#|)kDPty#_Y9sibz~2@cVg628%gr9*Jo;@AAL38qu(vLQ%i@sji}^|V|2_@<%u#=qnEzItp#N{T>1R*s|GNezsxL`WRs9M4#|Dq= zGIoOhlu^d%YP^~>Od~12&Jv|nyhl#gPMI>P%UJ(_$z#aMivH67eRkO*RvyeBMrf@_3V8#*O7^ z+*soS;LPIQeT&)N(m| zi+g)LWP6A8LA>K(2~_Va7*u*!c~DB;U11_Cyu*o7KJOB!Ec^Slb`K4?iF>#Ho9!+2 zLcF742~_WcFsSr?4#$PB-)$e60^qzqpGcJQc^5%t*?Twr+w^e7?#~}NeX8Zb${PW~~?SD)USIoQSQ?_?lPsBSEmO%Ah34==S>u_AyyVes^ z0ElTGD?Bp=fOxkY&`7(hQ4L-Ef4gUV zbZ=gUL*9@KEm6wnodT7Xd0#mkZ|0daaDdr9=4;%H-cN}&i+MjTVS9&pBK__AUqj+l z@5wNz^iGB2!ro6{A}j9KT9lZcDtzAYP-&SrkEd}n`WiRm{yk#NV&1o3u)Upq5O442 zi1%<9RC@1*|Z_0ZioLSs^UM047 zfd}GU1WTZL+g7A|_kiQV-V0zN6>r;?d$l9iMQMAspQi2n-9T+Wzfsx@qLk0utrCxS z{=s8r@3)k=tufo@`FZQlWjJ+epE1{4o3WoL<@0v2=kZp0?&%VlL0+$)KVEOPul)1m{%AO}xcA7a zY;U+1@ht`a2$$K=saoL8W&Uhf?zH3KOY# zH~yw>>)tQJT8&$_qxFKA8EyJR9BmU$l=69(K&5rB$5ti}Hh(?-{Q~oSapCKC+jmR>AU`h|JI+}3tuL3wt-IVG028-Zo=T(vU%#q|ee^4sZMFK%4IyG->Nkl=6A!L#1WjOTS&( zp8Wp&Mc7=k{VESSo9$!XwQHIlu9$btT5NCE1BiDhEP?915(bst*WtLZcdd6#0U+MA z>vwOWl+QaCDlPNI{EQpI=Kc6TZ0}y_h_`PYL*i8L$uOw&PKD#b-cMj6mHRbXf4BIL z>8Zl!9S@ad?|qM0vzYhox@_;_M8wGkVc>m3c1mU$1W>|*wQ+WE&{o9#z6sART}eLufKtXa(a;(KiGgd>Qz zTRp_v2L_ei8{oLG_hpz!#e3X-cioJMH`14FuAlz?s-5nSn+IyDzh|v?1XNn)J^j}z zX78`m{pyL9yk2*)Icm0#d7mKGEasi<%=QjCh-Phql<)c-*ue0RE%V0wj2qeS*q@JsGwUC& zn0IU=#QO)t+rA;<-4F(q-ecjou=fs_NX0w3-sTQHPoF#**XTxy*F}%iJ8zFoy+xGr zdHXiv@$Ogi@iEf#m%{hb$o=Kri_FF`@3nAdaqp-P*xm_Qh<6DrfqH-L*w~Pa(t8jb z7xrEQ6RCKA+_kEMZD7x?;=}%YN&yNr|v$%KgM{I8g?EX9-mO%A>1cS={?)af0 zF=6j%Fp-Kk?fSi+DCP5Z`AEcD>Cdx28qO^4J+c|wyZ9*5-?^{^s&^p_D!rSzl#+J< zOk{=kW}=kO+o{=`@*V(Z7WeM^G26Qr=A8mdpn9K&L8W)y=B4D_A11QGdpS|c=WYM- zoAT}kXBPMNa%Fqxr6Tk@q&4d54#nzrS|=>3Xwq%)53g)58_>uGxm| zov;h>4uvI9y;s7Z()&6b7xu2z+7tldO}jtuO_cI^=R&1r-k6_pGk(7|Zmj)^ZA=eW z%-gOV+uId;e=QJ}K=qyrgG%pHa9r5CLR(V+i1(dxC)@3JIoa-l)2Vim5A)ic`Q~Cf zEm6wnodT7Xc{_h|yAA1A?{jan&#T2mE;ifOZ{(jR_n#7L7W01Gp6wm97wK=`c80{M z-jiWa>75G4g}tA^L@M`dc10oD3PmB>dPO1H4n-l_o<$+r7VS+>6+Z8HsI<&GXGDP6 z=aq)e=+uGq{NL@M5G zlb?6;PJZ6$=;7y`!VW#})c?TqPW9ca^^S&0%e<9-2LcPt{yymRm9|HWp2m%}e}!1H znD@m_Z0}z2h__ou#M=i3mEIfRxUlzSm`KH&cKxp2$y)CSsI<;o>Cdx&f>^VdceaM@ zoris1(ZwC{_Jl#D_hL9M?41J>S>bJ?vDP~jD$CwGnOL)!ccPZ)yiudOWHfbtP+n`w!(ooaZ ztx;O_Ej`oE5~Y0J-d;T3_SY-v$osGF{){zyKXrEbJ!bou_d+yU@LRz;R*k1u&6{w>I=ny2Az=-FDY$x)xvms2jGjM3+I7@_D;;9gJKH<*G2)#MOQ3o`f4zTep6=$cP8M>i9teBMspBHnqq-OS#9X0RaXQu6K!6RCJtOIxD3 zqg$eRD{F}+_xKXc?(8L+aH5pYy96pNdp#CoQ`5||`Sst--aj36cB9!o=H2cKLvG^U zt$VY*T}zPuj)o;ry$`~m()&3a7ruVC?PUr8`FRQL`aO{-?ec0X(FA(ntSOV31D-0^V@56Cn?f!Nb``GvMr^K4YydMu>d-tk}yuaq#-;g-fdom0vy;I@1u=f*~ zNacRb{q0@p**?|ft2H*s*S+t`OIO-yTMRHgRrtK)q0&O{e^brgFTIwu%51;Wme0)g zG4FfCn#H_t4`h2szKwW$e}#Athe4(HZa6ONeHSKD@y=;^VdclHprchGa>`t33p@%Ds4rT1bu zF6^BH6RCLDUo}Oi{IVHht#>F?mc4f}v1T#vL_fB7LKURHorWUbEn!gUJp+yldnds} zD&Be1b7ke%1EQ4g`W@(Jc*te%9S3LDKU^{I*kNq%UjHKfZSRkGH-tf@_gFYC?7agf zQt|$6+`C%k*Da!y&)av{oAO=@XBPL48o~C?tBmw_2`qtnf9^Qkkc`rM5F8iwUIP=U zc+;-mXNgiiZ|@Or%6lQ4S=@WxD7JUdTZnfNEP?86JCg3*1C9%OFMx@x@XjDg`Mljm zy(#YyIJ3BS@MyMoiq}?mHpi@z>t`*_cWNu3h(_yDWA8?=r`p(8qO^4 zJ@RX|caROz-?^{^s&^p_D!rSHDJAa!m`K(8|F_LVDWA8~*Kf*u0GwIeyYE=Gx2uGB zr@#`Z-sfRZ>0LLll)U@HL{@k&CrbIe?Z>_;?{08rac{5jZ103e$oKPjSOV2M3kH?m zRmPQ)cUPFm3h!{Dl+U{aD$D-$SiA9t+{C?G2eG|-*&_WN4NIVUAA~`r_j5QdeEn`a z!4v@U^Ag(q`9z|W&$|dJ%ig_YFc}2~_WuFsSst4#$PP zYfUx#Z}x7}2>x6T>y4umC8z30N9()$z~7xu0Y zYzhGJjtqKNtNhXurF`BgP+9igPl+{)c|V@U_V(+5c>7K@Bu@3741-GVR5&i|{RAdb zyauO zy0zZXP+9igSBN!>d0z}=dxy0|yxqP*ynSF$>AeAt3wvLNiLCIh9%`+31XPy2_X%Rn zV&2&^+1|SLh_}lO#M=`FmEMctxUhE)Or+}l|C`NBYrR9Evh2N+i8YIPC(dSj`?W^A zon|54En!gUJp+yldnds}R(L-kO8KtefwK({x$M2;;LQ4mE9M;=&h~b0jCk9JA>IvP zQ0YAujthJ5fQhW|zD1PsdHaUHDetv#W^wPRxoq#S_Yv)vqUMMxA)vP<-HKjEbcvT9@|^~6!9*CB~ZO>zomQkfaAj63t%EuZ+VBL z_{tzk`Mllcy(#YyIJ3BS@B+5C?jyuIAC^G%eguQc{_Z&6keIOdG?+-mJ9+<7t@3L> zQOf7-vfxd5kA^dgdyibi_KsHi&l$EP?8M9tM@(b-ybm@BT26y7&LRzqXtx<@2_WcvIfp;LPIQ zUQ5{C&e;3s@vsD{cNPpPy{jxPCGV~#=rA47rJWw_e8f4r_$; zcQh=4>U|IfmEO+iB|5) z-X}nA;S(U+`2@)I*IMfx4V9L8A36EE*}o_Gaf{Vv`;BVUHQU#3tiK<8g;=wg_r>*W zZyED;TZef2z@XB50~{Cjz6=woc$W`rpq(?jf%e1M4YcKEH_(=!-9TG?y|vyEP-&UB zgGbL4(r@Lz#TNS-H)H(?V$EXS*&Ep2VeOFqc8Ny3Jz-Gky%>%Qd*{GJD&DhdO-b)m zdrErMT2s=m)R>a~spFJ%n+?`_heD-g-pYPGx8K|B_pMFt6JWNl{PW~~GO=bc@5GI4 z?*i=l?esn3-4X_s-ZS91uy+znq~c9`{r!L_<-2|dZZte(>%2)n<7Vt%)y72aowQa*3*EpN(uA)Hy2!l%RW;;sBI{+q9@ou&7w06S!pR}VJ=(Izs?$o+8U#Hznl=68y#qoG6{mLzm zH2ZyPTWhT_+gJX1a(@7vS=_ttF1EKr65^c#OQ3q6he4%x-JPZ6-5(}W@uuCMFDFX* zyzO_1c$0p{&C>7Z-QdjP-d?-e-a*-jcRVbC>YW9HO7AN1rR3ceCQ|XP`0lC>m$sbl z@R`kT9X^b@)8R%+Mu%{sl+U{aDlL0G_Mi6ecf>q5+FrBx{g-yT4Y`SXx893*ry$e_`5s%sZKsIHAEuCAR(l=68OL8WEh zMP0&B?!J3BRkUpv9{ zaK*f99$vwOWl+QaCDlPLSy^I_7{T=)B z6%Uvmu9&yoA+~qqF2p+!mO%BM3xi7UQ*d0^yTUr^0bz? zM7+HZBi_SdQ0cuJjthI=g^5(WE6%#5J@oHY?Ye$>+F`5DYx7z>)Yeb3);k(1E%VOU zA)&9Y`?h(<;@@|Fg;=wg_r)V@@4N)W+btRK_JKjA_XapF?0p#~Qt^K3xk`6Bhz5wsk7j+N47<_~er+1L?{TDq*}i@w$I1P*aAtAu zs0_Au-ciK61eQR(KX=p_l2LjOg5$#8YhWT3?{zf`wYCn0+ErBxwL_~EYQ60XwP%S^ zK5y>~9`AQH1sx;(vSwXNCHI^Cv(Rjx^fhkAKfe&pEbcuoi|y@t9PuuKB~ZO>GwI$v z;JC2&0+>j}yIB6Nmy?>eL~FDCP5Z%i{4?`Z?6EVAjuDnikx|5yL__Rd^x9ry*!a9JewC~KX!ia}Ij=SrdpA98 zdbnb*zZ?I=_D;Y)&lCYmpn7kGL8bS7I47s-jn9sHS;|7_qS&Il>%MO_La{Ma=-RZriUx$UGps4+ch5P?@(9* z)q5ojD!s46abfRTd8PmmZ`%ENZ=#gXI~OV~^CrEF8|(YEabt~FJZpNmV%~P=+1^3+ z$iHV12uq-P&xJvy_bE6o>|NoUDFDR#T*j#m$188?@Vw@_4k^DK?66vMv4fT<5AJ0HPzhb-L7W(-Y{buxkN~~GT`|$;~xATp}mCS$N!1uf%ajN%Z7*u+v!f|2m zCoqx9{hD*nliI;OPHIy+DXbxe_0 ze3VkYpJPh>OV)ZvL#1Wji#)5NzTRtUqn~HgZ$|Gc#G1vtFJ57Lhn+_H+wC&q?E`~K z?+tKV*!wa}q~cAxepkO@t#<@eTINl988@S!akF&)1hHl@@9b-AZ|5tBx64(;+Y<(r z-izV5uy+njWQDiQHEX>?p|b3~lZiEpc_&_Hd;9&2csu1I-YsEJ={*CE3wtNQL{@k| zAWHeJ-+|W+54r5Uc`L%Fnaqp-Cws*`$ z#JdERK)pYAylF^A={*RJ3wy7DiB!B}&pp@vHoB@uY)%c273noST5hiCah53M^Y$*_ z@eat^VfJ~%m3{W2e_s^yUI=Fv_n!9)+uQFd;#~wwpnBWhqI>s%SkZo-$B5#o9<9=6d1Mf!eBN%q@OYoK%P@QY>|A39i~HHQ8T&m1&MfX7{43kr z`A5V%AC^G%eguQc{_a?4NKDv!8cd|(O}jtePn7a`yZp-IjrFT>GkO{~*8XTXv$*%j zJ8W;ipAhd{SOV3%5C)ar&2E>HcK}SJ;yt)dIi2!rGf~Rt?R1CB+b?`S%g?x3Iz9l- zEbiU+9^!ox@lJsyP`%H?pwheU-BR-I4-=_)ZySF>qx@Pumq}i77QxAtNd0<-d$lL74OCkA~njdaH5pYy96q&dp#Cb)u9FH ztK7$)AMJiOFrOH@_FY& zW!Zbz{?qhu#k^}4v%RG}q`yO92~_WuFsSst4#$PPYyD*kfYZA-QOf6?3zcQ>U9s5o zaK*gs9 z5~Y0JDNt#hcZJ|tN67Ejv5{eB`{eg;<7WKxPl+{)c|U%{_ST(2ynP=U5~q4khC!uw zDjXN~egYGz+^@x6x|Ol*(yfdgmu_XmT)LI9^U|%17LQC%6+Z8HsI<--^E7ToU*l%n zzelWD%=`9Zws%23;_dx6;yoM&mEODIxUlzKm`KHYce{R>`maOn`ei1x>zBE&UBArw zkFE8NhDyu44{Pnw{&h<9Yj5;4Zmj()#G1vtFFs*=>#*RDY(>27pCjH4VNmHk7LE&h?|_L^yd(GBIx>6Tts_zUZXNkx=ba;K zzp*`fizwyu_I)AZ9kVjT%zOOLLoNROifiG_;@(j&+1_DUh<6DrfqH-L_^%-urS~8> zF6_MqCQ|XHUBAx~rF`DrFGak`el>1nzhmPI;mqRR^K8mXwvr^hCrQ%V+VNw?`A-=$ zVZ3MXq^To&=(Z!?MX&^_x2;rOveDnKNRsrH_sHq}Mo#L!vzjFJfaAj63t%EEyfcVW zK5sW0!=tk9`#I)m+*tl0aAtAuU|Y7gb3Edm4@;nWKY~G}cgJ#u#Du-4!9-Sg?q zUA4FFb<=JpO8LB<>_og<++A$;?-3pEveV+vHw}O@i+lI2!1fM1f_SIE5~$wiVNmH^ z_pMU$?hg~Gc&D7cBkw(ZM@~C^N4C9xM|Nv>M_x{p@_E}=5b;hbZf)kx^ZmUWoLSu4 zs}kb95AlwNB~ZPyU{L8@rD7?0cZG>mypQ_iWE}L#$v!AArT~zim(cFd zClaN6-bGMZI^LMCaWme(HMKWAT(Q^RjjOV~bw?5J2v`Eudn*hoz3;haEz^LtzP2@0Bp9^u7+qg}rONZ3+PK-f+T2ek;R8E;;NXk2vHa4>{x__a;jD zymO(_GViHvzBTjBpWn%BzvRFZi~oItiq%XHSIpb4I@>#D58@pNOQ3qsg+ZnFDL5|d zUBST=0OB2$wX^+_ZP(f#8d|Z#Uq>o-C@P=VUQ3knd8a_7W!}wdYt7yt56OPf&iMV= zxLLaYlvuNv_v3fi-p&b#w{LYr;#BX+FsSrSh2z5BPhcXI`!(A2yTv=ErwX5UJXBid z&GY@*xUu~25o;FnzFmXu?YA58_I5av3hPB?&P+9igSBN!> zd0%{&?JZ>>-flG!Zyy*`dT)T^!rqr*A}hSBziX{`1XPy2_X%RnV&2)c+1>@m5O0@S zh_@#UD!muOabfQqm`KID^YBR-YbSF?TIW4|>ru1! z(_+UwHrvO(|0fe`7V}R058GRZy?^dh2k~wRgG%oia9r3s2_{nUKD9kSc4+>$drX@s zom06)-HWC_ravG``L5rA|1msd%e+TTe`@yk1tYHF*;k2epS?eloAg)@tLN4>}P_Dey$OJE7q`*X*7hGdl9gW$NZ_ZpZ;#hZ42 zewHZZ^Y(s^$D7B~xEcG|xEc2s!kNXr=Q*>zrBuYb2$n$gwtb)O-2;vbdoO^ARJ@-C zr|eLEWe}x&-fqrs$~y$kEbblLfbA`3BHsD11giHV7*zIm$NGlEguSQ1L@M4RKByoo zzxETQeBLe%-jw%fIJ3C-$VQ0wUc@^WmO%9`gh8cuvxcSQ9RL%lc#p}vv|IVLnJDG+ zc53vdya&LU#l8D}!1k7s5bqRN0@eFG3@W|rHZCRa{xFe>H|_epoG9h| zi+g)DWqUhsM!e%;2~_Va7*u*!X;MnwU11_Cyu*o7KJOB!wCwemely;088>V9+ch=h zChpz(Ber)z4&ogROQ3omgh8eEb2u)1{ciiADFEc>CA9vYNR;w<7eQs&dpG^a^l-&q ze>ZN%_700dydz)h z3s^03wu}i#1sIhx0Wd7^G<=vviE*UtXa(aaSOJ$Gxm8VUsproRPV_!sPs;S zT-Fg@O{pKqkrl9}+fqpaI&tDBPh(t86O7xumk6RCJl*j6A{*j^w<#TCefI|}5j+Y03B zt*!NrfJ)1}w_kZ`_IW1KPrsd8eBWa46U3UuytCV~z5OB)Z-S8NWXp zH%s^9;LQ4mE9M>R#`gA$K)mfcAl?mOQ0YAujthJ5fQhW|zD1PsdHcG(Detv#W^wPR zPHgY6ZxHViSOWF_+_9q}8Kw6iI4rVIX0mp^C7r;a+-f!0#=TZLG`5u#ReD4wa_F9h%Z6|nS5T$(HZWf5~$vfU{KlL9c4pe!rs$hA{Fn5lW%2wx9_oT z=$5m(?2U!G4{kYS>?cb3yj`?B-XEVSKtGRoJyc`y=h;TXnZ>pE>}}EbiUci|y?^74c4iB~ZQ3!=Tc;Zs$_+?hg~Gc+>9BmlLIY-u7NR z-b!DQ{cdn(ac{4#Y;RpC;vEl5pn7M)pwhcams0ZX3KOY#4}Y{Gb;P3;srvuUezYR> z!CxyK*yl%THpx^uW!=@Ut zgX-j?e0z9qM7BD646@nl?>(RCDb4=)PD|`v!krtIVt@BtxQoI3I`m2u&|wUutMxdY z3Qn#Lrv)+FsPj6!2Z@TD$A8PqC*7ar6R-SyQaL}L?0uF`%%0_w)F=7mVopApk&{n) z=H!#MIr$_lH=opbnookC=9B49^U1xZ`9#y6EMWSiHa&G)1>kpy)#y;wfY;OI2 zf5>?KiO@5p_x;<(i~02yNek%BY9X@|wd&0goLs#N>*=)ptD&)v*%|)h3CC>V)Tp>fTQc)gGCK z>SbAm>fCpR>VpufWS)15UBqli;huLY@6jG=uLK`5*cR+1&X37DuA^Tz}Uy`AEBLzu97@Cw}O8C(Suc=$ohCoyR(b^6N@= zRzO#Qkfv5$g@co;E2rO>ZPR&O?SVu^bX6SlCFu}K{C>kIl<7U`_Z#h@rS$R6(M$RH zuskKeM+Ah_%0~=1xqJ*+q9=T$K%%9<$14aW&WH8VALU~pw3Np@NWF z`N#k#mybEi^n{NbNVF9AsJ5Kx6LCJ=p{DfX$4pj?@9weS9#s2xAnvT<=Oa?+{BjFI zYUQH6A{MXZVP)?G8@Xb4p@*KJc)F&k32>$b<+ z!v(+h_PC%7dRL?I&7>~QJuWgk zavkrx9h%ZNxHW38Dc{-_OC@>Yh6qQRFB{Px8L#e0PMlvZ{zAe`tOW&QgrBecn8u!*ojbNv$@rjrzug0 z>!@>Ak)3k5FFNm;T^@z(MQ&I(1L9Ys_S|^w+}k4^U$d))Y>Ow!DBrXb__wg!&rU~v z_WJKbPnE6?D{ti2p-kv~bLDzw$7UtsIM^@=W9%w`56;Ud#|lbpOl>50=G%g+n8wt%_mOy zXRzQL$*9eh&>YLK5sQ({<-fwFZD@Uu{uN%obH-p^y=clw8Ggor8*lSC{F^~+|9$A0 z($m|}o&0(u7X5tQdEvQ@*N7&`Z^=>t*83pEHOn^H>(Q?^M~i@o&n;IZS`2x*7OdwR87pm8N|< zgep0`EFUAG zrgT15v0_N$BYrA$80l~k7KZ0=f@2#_A?t$3Vd{hP~yjrV5ljb zk0Y!Y()h4F#Lovw5#Yl#is?bEd{~2%%g0q%uJe4z4-|@z_KQrEX0z%j8}@6ayfC7< z^67`h$^lo+lo9XCD0jRpt9&}SnsU{)>dG{^iLz&gsnV=|4W&BWQ2Fn$3d)gtD=RxJ zGEqiCsFJ&$QypYBrf}mGH-lo(813p!3A|&ln)0vXEHp;Er)ya>SE?!O@rON`cy4p) zlN*BTpFAi7eSe6%zBoGtiqG{Q=}`%758L115YscIcRjZ`nqO~yT6m?8Fp$am8*6eb zLrs}5*>$@Aj4}N+W-z3xRc{gCaonR-Ms5x1wB)GdaHb#UvIKhf%97dq^ebKMn{=F%+=d5 zSg!MWvxs3fKtyjY+il35&dtfd?F~ureM@rlFDqi0(VYBsx+QroZ%JC$w;{fFt%<=Z z8`Ai=HJN_UnsgiTGudU*l7vjQC3f3wNDzc7x$|4ZF)4cc^-C?p=bCPzg1n!a^a6eF zu0gDwApaMhIimF~>~jo#kB_UjuP<%U_x-s3pA_9ue6IgYc6Ahw?f(irQ+j%{jpf%{ zP=bKoMjmH&qE@{Hf|IMaMt?AkbY5>OAyE;%6~}nRNeCr=zfk}+rQdHfh-La+6GPhl z#^zH3d<;_vT>n5wt$aj)lgo$e2|eNCFeEC%$NcM|F72;{y7apm>f&=X)aAt0P#4A3 zP?suKLtP$cgu0Bs66)f2In-t7#ZZ^(X`wDvuY|g6&j@w-<65YT&5cl(pzEP7)lM>f zQgX**>r+gG!rgDIJQ$3ACy0Ig(v;|I7xX(?T>s1M+tBY4J@agi?3@<&ko`|wc{IQI za*`Rcx$B?*yfT`_Pdwr{*XNr70=FW?Lv%mX&ugVGhdh;3~ zptk}@Rjb~NRLmac>g^aT*ZJeIMI5sMB6?FkG9^DhG9?y|Oo` zO6oi^C1oC&lA8}rNy0-@a{r+z`S{S3)Och{+C4HQy&jnoP5U4SRdRZZh?k-_?^P8A zd2jELD5y89c9ux5FPrQ|`ntJ(2=b5kmI3 z)vM&rsz&pas#g%I{&>+^-4DLuVyPUhEJmbZZ3G9Xp0 zddmYRS8r>Q^h9r8AW;#$703NX^JJz^#P2soLQU!S8>?6`q}^}CpW)}ja-fSS_zNMps2#z&7-em>~Q0({t=6X3%goLoL$!*ZSH zWBB<(@v-mPT59Q)Rn+RP%c;o2%c(klt)M!8Sw@X^SVpbgxRiRaF@$<}%a1zSYy{<5 zaR%kqW+CMqvV{8W>}twm@_I_so`z5*cRhFOPiA8ZH(oKkT@aeDVPF4f%H%{R!SP`? ztF37K*{*FfWcLWUgKUHDhG>5CmqYcD&5iG4UIWc{4hj7W%@18Watqlj_N616y*@=M z(=(-aJr{q8UvEK!1oXB8Qq_7qR)LeNw^0|E?bCU^U4}$O&e!&vHmTbTT&niiGFM%B z(0ujr?F-d|qXN}$M@?7vrlzWgRq3Xl)cZ}s(H%)Lj>nPs>C%AoL{+Pycqo^SVXfb$R1{?xTxYhKA39D&~XRGPhhT(K#k8t|t-)rdC zp6ltgw>Hw5Th`HAJ=W3()`!!rhJ?{quCAozi&xQ+5US+PZ>n@Ddb@XbDdLsQr>1PU z*#qf?>mRlGAkw2n)%M69U|N9eicx0hd}rg<2HD*8-I>FKS+ zWqMEg{e}WsYGO#c-|)H4&xhqGq3a(Asg(~EIJta`x~3<5T!utN_{gq#ac@!o-a{yH zKJ2dlC?6xBrF1@)-{j|mj1}M`8A591;}$r%d@Q`7Cw#nsL`C>`u&XX9>R+9kOrMDJ z(GO}$KYq+-#gKOVIQSPoA2MG7KC&UCRz5y}lgr1>Og-VF>R(KvB78I)@x;2Qe;pu{ zI3NB{Q#v2pSTUsWaq%`kA6Y`j4})7w4{GJ3E;zY-oQCB(fBn(&cA@wvj_Z#>5K5en zaHuJrk3?1sX?*10<>$l8Q{ebvbw_{?M{siacnHgNo{wI4OO20N5K5en7^o?okNd0` z()g&H#m`69Bmq8@_XPOx1Sgk|viF%rI?u-xNL1wfQXI#R4G>D4j|`|OosX}q7}EH# z&F1HW3>DyGWR?IQf#Brw(ddDm@UapS73HJo=c52>O6Q|NHq-B#7}EIY@ra*~ zEFnIEA*9ypj|gyb`EY%xCwv@+L`#8>Ob8{;hv_4x_oVZofR@tv@X6ulBho|Q_^|^* zYUM)(PA(s#9_tAomm$$o;Nv}n66eD%=STS%0WGETvHS@?A6^p#_(+D3TKTvIPA(q{ zbM=Ie7m%nZA4UJ&vN}(gJ`v}mAJmk7{Fu**A?^H9GoPOidVl~Q*$`4IA0NQUjEj9+RjDAE77ANtKi4q?gK^WT?zZ+9`9g`lLB=IcZMpW6jC)aj5+a+HYY7& z%t`DqbE5pioct1NPCB13Cz|#F5UOOqSG@HZvq6RXUh$;mP0=@h;yYrSJtw3o=A9~{ zZw_Uc#G_|kU(Crv_RjNesQ#Ofk;vXK34bGr8_(^ZE-1ev29C)7y;gl>U;6M0J=5DY zXBD#9>#vy4^i=77Cw22n0UZ(n9ZrOFwdyb!oLn8+Jl7K)u7gBHbeOX$lZ1t3l1r;I z$=TJJWa8>fk{*^xYOTs73sz*3m&-Frt>u{{epx1&yCRdstjr|kR%Mc(R%MdVRhdN7 z{u6{MSsgZgDMg3p`i@2%vpLn2(Ia-DcSAln=OCRWyj_NLHF{DCvOkzCKz7_gYh*jE zH$gTxepu*Hl%MDI_Q*cDkU~0pubhPJas`RVX0Lx0^i=8Uu<~nu9cI}J=&%6N)v80I zSIl1L>hKsW*ZJ`pi@%u-5Yb_$B}3${Gls}-%o!pNT0TTxfBq18=&T{~z_cN9)rTSS zJs*b1ujdVsdz>F4?-e{mK4;7j`KG`j^7QZ_@?pOZk!#uqL8y{@z9XW5*_gsTzsP1% zQ`TPC!^^CusLuV4G^i=;?@Ju7{|0G<>)&Jb2)!RxXTLMj;P_9ck$q;!DP(ik_xei< z6mQNR{@?8U3O!SL&v)4V!>>14Uje<1e9i1ct$GUtCs%Kc-Y|`HUT-TQQ4zfr$N1<; z2qk`hQUEoj-=8%2hv|3e_pd$P@$*6C0(=BRNUeNCfRoFI>svkH<1i#z3VdWjC~-ba z-!Z)>oeu@Hl+K6Gzx;eyItcKw143%$Lj_JQAEVyu2_Kgs(Nf^!J%keH!|vZ7@hl%YMFA1atuE~tqY8&TA#j1t!?$5dUB_N($e2RS^ms>YGk<&l+mCv${rt? zJ}H^sIrI3$ti5o*a~8B0|85fZTB(802K27VoGwk!xB22+Q;?tAzT-;^^e)M%ocqYW zzWFt>x$UR46@FKx4&}}J?#T)0i9-F(nb2?1e)~2C``_<=N1%tS!hb8VkjZ3KHDBKI z4w&FO<-gDG_3)wubXE5=v%|FN$_|`dUEPM|I)B~f_J!Fx5nVOu_=RrR(m3gi+%D;i zuS1e!NVBAe9cm=ae)^2Ae=3^pvu-mT*LEhoHKQB-^~e&s{q<i+HBaOc;X|*L@P%oFOltX$jyVVidE~=r(ejZm7*|zP@Aw8Tq z&;M?gru6r$irxilvGya%uS1*d$ad+x1lb|w7a*IhUxlo~f08NP@rwAe{5lMB6wu)g zNLQ;4Rp8|6a8wy)8+BfXmmyIR9lrjwl?qGSLG7_TPIWauMR`R;Q;E0tP~#@;rL0f= zP8q#eLRnoKOGR~ZrG9HQih9}TSE}0lWz>gvYpHH^wore6+Df%HVEUxw#w*;*G7$EpMxeTnjy`wnbj1dNBDh7uD`wQFr=An`+|_2Q*S-8x$UX)gHilsHzl%7KjZwY zKbJ-R>F)f${doj>M)G(C-|ywH&v}~ve|O%yQ=VUMUVQ}gW?GKfiCXn$4Nk7!uEKJi z*PFaNvvneRD~|Ds@eoS zt#gt6Y2q(vj)&X+50Cw5{a>6fBfD+1AF>0KGtu{uxa(6Y@bAG~E0c@jCs#^9`LWw8 zDlt7H`FPAd?(*5+eXlRRvVh)%#*cSEs#=f7DsXc3Hp+_CR0?k z$z4@#lBTLnqExlXELCk%MOB-)t7;RYxY}fKTy64aTy1hCt~S{nSDVDCY7eUy z6HWWp#{b*rCG`G#Whr`VIib4X{LHQhf_T1=vJ=@a{b~r#-#FcwjMi`Fuol@nrrRNV z?JFmwKek>pCBDK;6wmkF9%TFV`xWKKZhr)Nru6h?Ta90DbZ3F{n`sqhCu-H3H8{C? zy9UT^ZM%+`tMEo0hDl}CknD$C1@RrfL%sRnghsIs0kUv;96ujrwL zWmX-KJ}#O@Bb(da>Y5>%-&~(*fo#8)hml^Q#~CBz{s_g}^SBL~AD!8wF7mVU zX;6*nnbOl+4^w`p zK9<+!=fhIyxx!=!sg;jg;Ny%S=T3t@rriOvCdO$8U?%@rpcaQ7TUelYDAA~Bo>$#;r zF&k63@rw1m%+dHO`}#*yd~Ld-IgmT*L&*NQZ)3sn;F{}$(E6KnTaWA%MGIt)ZD5V& zc)0n*^z%aTY~%JL+sa}U%8%XtCGgkEz z=0Tz&dYfZ#hR$F2Cmor7gI2b>PFr3{r#~g6(l6e{(@Vdep)VBNrZ+WsN{@Q_k{+G# zivDwCJ{@)?gZ^;!G<|hUG97AghR%XeC8xI!=2G-l+o%dJpPEwr@3!dsUA1;@M)p5< zY6|LO#^CX2{fb$?A$#_zTF6eThJWvgtrtz9p1Y!WOUyPPd-tgzlpnkOi26*=l%C%1 zSn})5QfRy)8B*1%w_D)k>TRKgp6KlbBr2k}CFdjMRVOc(H+|GbKCrJs-okQ}-1I@H zyw39z@*35*$T!%QlN(HG=o~O_YJ&5Gr3q&%rp6!c*H1n=ZM)pxb&uTP&q#Tn2LIdV zB{M!a(Nc=u>c>#qUdV3Aab$+~J zxD~T?B6=&1@rqCgC4Rq=3^k?SZ@gs1kaoY}+?1aWA~c@WuaN*B6T!*lqef$VB>uhuT} z4QyOCRIqW`WMt#A(#Xc;qmhk^rhO)aqGU48@wm!=#}1jy{s({0HKPgB+jnI$S+(wC zW>WzH{++x7yxn|!y#vN-)~YG#@UNz@--|i+dJmdc{JYUpWOqHPLiW)syOGUZpHFg% z;5=tY9sIjwKMi{=Sie%PJMZs2wQ9<2xu#FQ(*wI(g`PWM`@a4EyXQ~lw&2%KmaD+= zH5^jZdVGxnCs#lHo9T&u)R3r%ep*aUQ@r*`Q+)PGQ)K(3Dc1O;DSG>)DJ*=_6i+9m zDeQgH6r+986kUAM6hS^|ic3Cein^226hBQ)Q#72MrqHyn)BJz?8eh+_ceJ6mO!A*; zi=ybK$xJsi?_qIv39^rE@@M$)sLm&I5cm=^{?$S2l009;zAdhpQsrjZ!WC?4^2?F;-<9JVoW4JY9A8z;x9?pBbv#)-zRu zY)VQ${cMY(pQV-Xyq{y=p=cgZ%Vf^9r>GA@Ip4Xe)i^L zyyv?ku;nGMpF1u2^&=Dd-jM0f%+ArOA8T-O^>Y=L>-_bbyd|@BBKj$g>-+H#O8okM z2h@~)eV@jP@!j=|=GiPwDW@5ng8%=2`P7=9kF0?L*C%$Z1o&_VCzp@cuw3W)7~ZCa zkqtGa^I_7K>32;GX?zTI;OB#GBfy70gw%R|Sqe@rA8qaRgpaL|s0beeMxUf+`W&as zn*Bkgv^++s8y%v2=)F|IiJerZ2HU91OLtT2C+w$=)ZI(X-+q9K*>aSc)9nQHp#2HT zI_(72Z}ds(J%lR$@qvPNOmF|#_<-kVKQvF#W#$27f9|sa*@LI@zpJGwcReG}yoIK) z$0KYGZ9#te=3!)W>-V`{8I8-b{kQLBDZ!O7LnwDx+U zpL>v~h<>(`W_15Djp&YlHllwy(vbGBuSaM5)}jwvRHv7Q-eP3U`GF>u1TA( z|B2opv!r`hZ%PmO+JrXP-jtqAn$aCP{BK_u@A!aS$D-)R{ge#xnR22%vhQ{>L$=vo zBV@CA))cp1P0&0B*YE$hIr9J8+zHv-`X3gpL%(yx_OF61FM0jkapu=g)`gn%2m_g{ zzp*B_GMcxZ|9j!Nzs4+p6t(Kd$dTD|T>Tt_9U<3 zH+egK^xk&bu=5Uj@9G`&yeB*8BU5+KvzqLn-TLmJ7ku1K`z_s0cd^(`e`&CtK3j7; zeZ10kdKQE#{_~H&b5Zou*m5P}^H$STWS2?Vi|m#1jmT#6tSR%Z#|r)~Seps>clOf9 zqzTq<+PIku`~1a@mj+v2^7{EC=hu&=lfe1M&V|`ITJ_@&POg4l!*ZS1&v1F6^iv$; z1ECN~{Q5o_YD&Mpf60m=?fTxF;^%|h^Ep3)@A%qJA;8B(aB}&mL6}B5&&NDSROI-Y zl2FjJsDJw)lsF&RP*XY|CKS`}((nJAUHSP4dL+PyKZMkJ{8$Q3E+1``dcwz6NK}N6 zI%o40Mg2Pup~U$xaAkT=Iv=f|rF1@qcIM|J@=pOi!XczqKBBf$QiHh)1 zrp-a?qW(RBP~v=8b^cL4dP7U;e9Y~_&xhqj0X||Nq*gvs!O7)gnwy^RaSsv|;iEXN zKMcDteIm|>5^736e)zItNW1>n+>M_Pa!r7b3<#-}k34X4`B>9cPx$x(iIxH%&ASzr zkC9MQIv=Z8F{JSk-<_Wi%PRtW6hKI=d>FYi+sx(T7%bQM>r;#F%m$PKA6+4o`0*nc zYD(wh2rGs(KJN77=Y#wuz=vrMrU$k1VGT|$A6H?y&hsJfSx7#LUdBTxaXxlHP3e53 zv0_N$<5O>bK4fa%=_{4 zktKBe=+{SpkBQ*q@=>EN(@5v}mvbUsY_G5xNIA&n2`0sMSe z-WE81_(Mpo=a;46A^I`55ZK&xh9? z0Y1VZq*gwnz{%yK|1WyNhZ+(U;bZ*o*JF$N_XI+T^I_%jqkQy+meTo{JBXhT*<}Gf zVj!eeK2pKSlaXBr3v(OjeC5>Yw2trccEAP(n@V#}8jt3~A?=&7S;xMCJj@uUAW;!M98%n3i~85xv#@-OgqqU%SjCDVjgR=D{Cs4c72u-) zLTcs1Xb7{-Tt1G$a-F|EwHV55fCwMOF@D+=LWv(gf}y5#K8~ypS<|_u)HC_husJPKHR~{ z<>NIh*LgmMdzBg=p%6-(k7TGRosXBS7}EIg8O_g!SB?N5{k#SEmtCdcS5o9lUmVt#!W@1QF)4gWVaM6haOSv zf45Sx)pUkp&r~nP2E)z@GSFI)9p6fk1))mt`!}PQUN7ADrcxJoM$fhVHs&;X?sWB) zBxEOrY)AGl)8xpWWil1n)=4{%ttss1a+RRlu-vdq3^SOIyeW}r_Z%Uc9)guNRL*3>_N6y^OMMC z$4i5rDLuW}PvX~`yywpS8xC^bTV-8*NL+=4?a%5a)LmzpP<@hB z!ps1Rgd?#H65=6L$^712%0y;E3io?+!!8QH)BQPpGCKF258Z_9jddp=`_7U$WM?fi zL0V?BuPM>{+o5kuZF<)l*<~*Mj-F8;pPQ7xJ~vvu%!+5*?DaRB#Pmd=es7NN_Z;|^ zYu+tJWx!;9UCD&Tt(HQXT6MJpoLpUX_hGh8=XDheiHhi|IL0NiAe8uhMcv6v?@7O} z=mIS@F{IsB1o-mvK?~h?MnOoed?bUD%g3ZCdcwyINK}N6qRxqE+RJ>IJ`v}`5o${3 zV;n1nG(Of&<>wu3 z$6i(pX?$Fp&d-NT=)D7@0Hz1E@?ix|E*}?Qxz6+9FuhQG6vy?47lab$BLZql=i?kJ zhBQ9j%;e`IQfS`YdWHZWN^o-dcm~ULo)3?irN&1Pgc9dN1vRDfk;{r9jgOjv{Cs$w z7dXGT&l2EcBsjTz7|&)J={z4ZAW@O?OK}`OA|aGGAGe^UbUrEuGX1WJA&rlaU-|iv zWeV^y5khJ`zXXGm%ZJSzJ>g>=Br3wkxZcr<2X~_tU1vO2G%~D8?9!VP-=|LGid!f0 zVCD$&$z(d2>M@es?cSEqS=GpKxA%(aUmqyG{Bu@u{zjCdfA46;dk9r>^CG6dGQD27 zd68;E&ZDuOU%zxkVfzT z$j-mn3)%b3UZQ!A{fFa`y)^SOvf1%wLeG@mIPIGte!T@<5YXE#NL8!e3c$(L+opMX zqPGh3nM6hO7Ms$5>hESr^*8KI?LRn=s@!xP6;)vmHU8c~>gwiX%CXl~%Ja?{s{E6! zRNd4C)a0-c)W?6jQ-1Z^Qf~L_QoB+bP~#y~$>}XPNQ&N;1mNG<$o?9Q<}pm~A4axo zt<}grI@TK5ZO3{byMLoFWV89#l&diPFF(GF~8o3&~uzB zNL8!eGQi2z+nhyuqPHAKR77vZalcV*G1DjF_Z#j|Q~LeJOjZnO_Zz!H1^6fsI3C}E zkXrdD04JA^O~2_09~DBGL`C_K?UNPpuQh}c=VKz&l+MR`Rt#x;oLS1xN7g$5K0ZK5 zt$dg+VY-*gM;t8I`SFUTOAE<|A0;c|Umpl1&c{-yDV>iKtQgYxc(k0K4?0hPkGjj4 z9@NT*9XPps+=k^k&xhOcLh>PNAuHmaAA}O;BMNFt=i??ThBQ9Pt>Wh+>xlp#jw=NC z=m$V+|lbe@mJkf`YON74C+hEU>sbLTWv~goBgI zhf}zo@UaIHEd@T(A(S{DMr)Yflg>wbXephKi|hFL@cKu9j|d2+1z-W@^7H$agEBYK=~&+J&OI&=glSBDQ_xz3-*du?F0PDF=s=|(~YR( z5UON#cyFT=9p=nGiRKgkG}ybJqy?l3kX(h{}=P){WC){AyVG%ytfa2`AzcsW%lz;GBeraxX-!mEv&go zE!_@9wH$x`Ny~wg5?VI>du_|hiyyQY>X_KPWyt@(cl>u=;)8GIZ??Yo@95vv=upfh zUz*1i#O7R@hup;888Ek4QS6=ra{bZ~cG&sJ|15+3UWBZFWrrWOy{^rdVm4c`D`u1H zTh=Xy#k-ZV4!7$r!ff&Sm!PHcSBIZA%jn(fTy^b-rAl=-mOF0`I{J~XhVdOim3kmp1Hp2Ej!2r0=&I59~61wJ}|o)n$a&r=Ac%!l)i@8zQ#tf`)lSz+>g49%eM5eXqB`8W$sl8;F{&4iD; zkf;J5xpDnbEKFzyMCdc|Jm)Q~0<7Atm`p1}DkKnq6kX#}`O6 zANZ&po?SkMLrwL3tQ5si$H&P%@_aC~`##bjq$D4fyM=uw`8Wv6P5%0{@*ZIa@_~=` z5K8&@5ePNa^RZtPLmeOWBjowGPrGl-Zm-aSl6=$!C&|ZESZ?xscVNn0Cv`}-t3o+KJ4TY-t5B9-B^Qf4|Z^!{_H>60c`gNz1S)Xec0z+2C|b{ z__L3i>e+%*=CGjeWnH~k>~|p6RX1byx$}K6+u>pf%zjqJfZb<% zd2fj9m=0gottyZGZe@J4W7PY6(^3my@x)_9e3=w`7u(+KX+>qnhO0yfEt8M;@gAh; zjW%8o2&qcyEf}1n-dZ0J_Rr+?wht0jI3CBgKgl(IvxiGh*~D!tx|Tb3NTE&g=6OQp z4hmb(-t&Y!9R^~o9)IJG*<0$pp=zPPDEwJ>x2@}9+NhF9*UF&4J=E<#(rd8oIbW=Z z%~y`R`Vq6mTAT(gk*m)W;^!;*@wkHDLWzpi5qVuPjVbS`O@K5db(IEAQdb)fnTf87 z92OE)(AD}w?rh4jh3w^N2iZ6Kud{#5OJYZd|H~FybDo|2DuQi2eJRVtG-s0sa?CS# zJEruQiJr@E-u0a2Je#>X^BJ@1kUQ%Kq4IX#^0z;Q9m?MQ1O28|#pVe+H?YI(LG=&G zo*Vdb!m2(tZ@B#MPR#C6{WWI)zNr#6kC@u49%gsBUjnoLYrh^_pD*Hh(bQ^9vHVso z4#VtGX^$~my#7~csr;QUseepfhx!f_9S%Pte6f-`oB>W!ht-ani4Iplq6#|9jq!@3 z5K6hfkp?x@_cy8>6WU$2fzh(C6O?n3C>aY6JyvkM`oaD=#B2o2qZP_b}? z^tBOk+J(OP+J+-!y9=T9yUIrkZKBMF57bnD{Foz(p>8~Dk5QhF)Y23_5+S4{9~s~z z`Pjyp2_M!*AyGv>a{fC6HwdN7M*!4R&&Os_40U{*KPAtHw=;zgix{B=CHZgwC&|Yt zSZ?y;FD|F@jgP(%N|}$6~!ODYb zH>11m>A&@LgC`Z&4UhTEx+Pobir6;M6{*@q7dx$k&aSt+?#lLhI-itEI)@wObrzqi z>JFn8y1mD{>yGyxpt}a4@^+l*ORUiH*&AnaYU6^9>#Vj~h}rul)yHhUh{t(0YdT@$ zQomgA$855G^|WQ!xRG|>J`qCxVmI;nK5aqQke4sDchtCidsHRH|bv=jLy0-SH>m&tE1O z!<|PP8wR)<{WeeIzPi2g>@(km>2&D4=Pl=wp3^H-k6wT5QS_qEfzgXUzBi1S*q`fr zPH2<7o3{)&FGR@Ryk%btT!RHFbfz+&5w;SWYx&r{9maUIBb6`>oLt!&vu#7xVf9H( zJy~dh#h>Y01hea$vcha~eanKsWBG~wH=$+nZ{D(J97S)m>t^>0!j~wiHy?14diw~= zP5!($`l7IR3VQ4K^ffnp&PC?&vR&-80w38`cM9rG$KPTrziq@;sPs2i@6K}L+nSq= zz5JIO7tWnz?33zgjJ{-N91+vpxHqz!G3M!OE*3)No!$~JsnOfw{_&U|Za+JY*&1sb z%og*@7uUqC*g3Jp;|$C`)9)5$|F~F(+2r2Uw8}lgWiqIy?{SbGkslFfb zgD8f&e#ocm@_YnUqwsMSLQ3+H2u_lZrB}^_kGGJh0v~qK!+&oSGgW{>_gYI2{GQJZUgjN%KJGxRk%qEY4pPxoyzu!ANr6u#f8}-PUy7o`1V~p>hiTv>b+|FXOmtY}wvecT4o`0S z;=Xl?ZL1Id?ON^pqfRTQpT4$C3A1i>%c4>%!>4~+h8LXLV#(xfC$EJTjEZbv6*aN0 zWt2svMbyGai%<4lbIQF+$QO4%2$i=w{Oyh!9qQ&clI4^yUIBC+R9kr)(}9?CzD$WN zgz4B}FMj_099JCkFCNBFb?5DAjl~NoTN~5)K^9^AbD&sFtiCwEuh3HYtHb*DiO_XlIJ6?I)#s| z5K@wl|V+gFNo{!g$<@tyxM&Tm{LQ3+H08WyR zc@NEmkC%|B0w0sEzhi7IC$kkxUtyuyOU+Ujm%j^Vi=oJs$~elDF4+vmXmlvN!ILczX#p*8H^I zI?Ub>+Xb`5*GYU?GRYGg`@L3ZDK^%;JQbhMUG>=q^V@x>j@e5G#bVpLa^D8C$@m@( zYEttn7t%;}{U^{;`Fou=D_LHL{xv8%?D$0ZVkLDr9Gs*MOFT6b9ZrQr6?FK1zJ2th znU2QiT?QIgcrixpy0XUYBWoC|R?`|^yh!KzjR=Y^J0zSb`Jp&#muAO)inV1mUyHHf z8&)u1YJD(loM#_>2SVko4vQqK(P8VbHkb}b&bR(HpE?J#yu#nu@6E{dJ2okU>7;yP z9cEW;ga5uKC9wlFUWXQCv3UBH8cb*Zoxq1b)xaOIe=x_@FogEmX`EyQ;$NS+iV|KTR zIpxg8^za`P6Lu>wW*u4=W30F%rt0S{F@Hz=9MdMSR!o707BM5A3vH6OI$ZHWjSi=E z9*61hOP9Tv{k;Ah%ocOZmrxb#=eWCN1pIpD#No9_*!~QRYFIG~A0pKKcSTV&+bhrQ# zRnTE>jC({tDCK@jGSpPxueDDV+FgCWWo|n)Sy{08ss%zgHA`epb0Ns(BAzTy;qP1 zt#gV%K_w#4dpB*dG@(uM?*19)bRk0a?pH&zv=QQC8nOz*ZSCOwn4h?3R6nWo0n8uU z1+%$c(=ppSVKHWt+jF{GtRc2NB3|6?2ClF93B0VJxRH+{*e8WirWLCFm? z$je%T))v>Gr=>M0zN7}lzI8!I<6Mx{5f?P;oC|vY-UT@p(4hN|T+r)-8We2Mphr_Q z_aPLU<^3Hczp;f-Cx^oyYWFreiiry+S>&p}R+L z|0*kd{Q@btpEysUChu_FuorNftiLWrE2pz&8N#0PZJK4COWdrPy5RrP&RdzjEczMw zNnSq@_LS?xU`SC?Kat=h^)uk3nds*XB&wjF+~_}~LMY|_L)}k8>#6TQ^no?i_aEke zk>|s^JcWK7663dOp^PVyNTeQ$cw?v;`=9WI#wsKI{qz%}ere0+yTn^;u1eZ1K^4 z#t+78^=ldr9Z2U6t%~5B8_eMxE3DuyoQmdL9>3wbZ7pvcbEvIxcd41icQ%WS%eJ&N z4*a>3(bcL*%zyqRVp`Am!8jj6<;`;kR}>U>Bzw;t+`r-iHhw#$#A?ib5ZMp2`69kX z+OjJZn+KU2ioaiJ!R4OVJj!&-6_|Y?2!Eec$XNRCQ`c=vz~VJOl!k3joL>sGM6Nw| zF!P#?KmKO9Zu2WDuPblb?@)aT3166`u6)5s>Z){MVI`B-)oe&q;kX-_mTEk5_?glB z&^_Y~=gUTm8*#?Hn{OCj-@9a7nP@P+ycT90ZnMM~w^ET^my66)MsuEwRFYS?>83LX0rVm z%wOTzSnfa~|t$ zDQrD^=dmd@{=?;O_$ zvrFEXg4u5RDws{ix0v^hj6H=zW;Dj6hmGAp{1=nAF0JD$6fc56h3^wN%HX# zmYX~uqph>WNAu&3TuwiyAynQRcQ4uqJCeQQE_(b7ACo1HtEk9ad`z_~hudU*+p=_j z%@ugOhX?3mzY=xFkecYv8*JS##9Cz22me-ZG6-8I8Ax+8SZa6qe zUG*p>?3>B!$^eNf9Cr`Si)V8BakTsY_l>{j)%x4{8X>puoHya$30t$YDqWGfXnq~% zp73+q+sShLt=!P!{#H8NCbowj9-ziUog2x{IeshMB4oF}5LzNvbd{;6%sxXFT|F-+ zuPgt?6kR1lnv%M*C?kBEq^@?ua+B9pxw66zDClZ(-$5QZ{y?a_IbY2#mlIv->qOHz z-{>LBF<nf-vMOQj| z;R}=0Rex}jx++*+SjpsdH31S;&{b~q6V^j0<$l5ysHwi6@KqE;T|c3IMR`8_H55LE zSD^4Q1Dqru)f~)(j}?$;KJalALMii+1~t|5QKh2L?tBb&d~~iP&qq)*3Lk+GQu6o_ z3{H}d){bVv$393jANYueP|AGRRT5fHJs+O1rg}cMJIV85tEKR<6+%k#aU7f^A0sN8 z2_F|BQ3XC)HFeS*eOX&)zo3H7{%twkwy^3t-_i|qjhmLxS&y{Vo$Xg$*Uq-O?&1_H zUGKG)y68=gx~jb^>i&v&#*Y6`Sm)lUdP~-X9Ji+EA$$X#Ot1LUdyAE0+f3DlgRF~IPkSj%3 z8IY!=uI#D`-zKT66R_OmuiI)m3p=2otB}@B*(HM-v;8htVHY|%u~*Kxu|a_&*+)@T z*>V-@uv1({vP+W|v7v1?u{MW8*b@~Ou_Z#Mu(jsfup37^u9z+LQFGnbp`soIH;sDb(Qy3?5bc`sd?C9f{Sv~;@3Y)pHNy;tZ0k|<<_oDx>ManQq~7Y)5cbdH z_4XSis-U+f!}l6{J_|O+c3)`pZ@t`Du;VV{^1vg;AkTfqBmEu|;*Qzk^@r3FS|V4@ zW2DBi+;6k2j=Zk?i&AtI18GX?Dgm6NuIAM?6J5Q8L=|+E8{-e<>j-V4+<)+an(F%x zb3`%J^)Elwm**pbcHB*bkdl04fRp57TU|5Z!@8c3r~)4qHnxk(>Bk>J<=u78lKR5V zWbZl$_5VtrD;zT%pDP^t0k_vrz~?5zUf_PBkAkYtrN>*gitcB+;_=AsUtT0TmYf1D zqxw3BJnoY7E1CYR*Ew2>-kMO3$36{&FHur&zThPFR@%i(^fnt3RnS|t?d6!9e(po4 zywh8TMvdN>r}ViH^k*c_Zxn*MkMQ<^Xs-)f$z)9+DUPCj{+e=7PL2oFatQJjau0+Smg?;O8h zz=lT?A=EMl_Y3g%4EQ!uqc_y5ku0Bl(Qnv=>5WUNgYh0(;}^_En{HwC`I0%;_^lX5 z)AjUjCDpG#+Zc~WY@ajeW%uV2v`qf#?NbwZy?HmK=*_jU@Fhy>ts^)|y`{r)lkdk5 zZX)cRlHPLReWHsXlyZL~25PGBZ={G~sOxVyy2jN% z4TbjQT??ZP1BseQ;toPp`}#u4T{82`|pR{`nD8C;A>U_TYca zG{Y;#@b`13)w49_!F$Bs`0**j9gbzH?|j4T99)78f>3#w%nj@ziwAMS-sk@Ld)cz-j;dE z>rLxM(OUqdDyg?6;3W0dNGI%{$?I(sB&wh{hcTlJPuALbEb&|65nraSN6YCCT7Lau zzM;&(O3~xGSC78ZrEK(1{}qky-Oo0ukDD;&Jk=xw?6E9&o`$8Gk&M4Mhfsx5&HH3p&qp{dR0Z$WdYZ*s_C=?9Y2X0qsHPd9m;#Fe7xBmvTs)JYmRNu6x$VkSB%(p5-Q zK_}?^1r3V3p+WI?HOTRv28G<#ph7n_$p4ZCeLAZ_A+Z{?{ZENqH9A3uzS57~aRE5zYyZUU>4$JTzB6tg^~7yL2WWCI z-S7CPY<`!o%_l2;a!2k$MD`1K4yTEa@)i3%`w4rl>N)tCeS7iW%>GSg-#<$~X4yb_{X~?f=w~aW zD0zK$9Gs+nM)Wrm{al1Z74#FBIE-;|8p9l#Kc0CQF`l{IeH?S6_84Zsjp0n<`60|t z)dn-`dk$bC-3Bp{hW?D^OD|@3*M3ZKZ9nG7-NDSX#9>VB0ssH5@%aMr3lGTte0FT- zfok-VsCU7})nkLEdx&`!^U0UcSARr{{cop#!R$R}GB7*v?J~^XR(=6yliTlpJD%zv zHQ55oSG@il*z>&C&-o$p`tjFN^pglFO6n&AoTPrX4Kfq`SPvEwRnX7+e>O1p`)^>X zW~^uCyj#!2Ro%cm>9>KIb94g}_HqML*eaMA>k-VXbqr=swhw0N{vOQO4G(5IjSOa% zqF`pjKO2}a5Gwc2Kf{Np(a+gAF$S?7d@ejcDYnIY@+B$I4bzvk*K*AEn6ebJ8wERJ zcKt*)Ti*F8&2V)KR8J~3XTv~GI>5G zK%xrA*B{F_4$J9hJ%m!`;|kPN&&O9$40U|eA1%*^cWnwE!$(s1m;p|bk7}dLgpU=F zr~)4ekgMzl522L#up1+^o_an!VNLaX`1w-!C`;jED}KJeiNp_KUu zfST(0*er^nj*s*H6h0g&d{|5rT2PV?2XK;noPy;h-+yuO&n6!^FMT1DG9Rmrb8%YJ|dx}dOq%nVyNT8YKlA` z5tS%>=q6G4=nqbkkAjnhl}w(G36QAb`6cINJ%m!`;|kPN&&O9$40U|epC-?TmUbWF z@F^5NW`L9AquNw6;bR3Ps>p}lGpBu+qYz4&k2I*Mo{uWigm&j+sN-Y)40%3mX~&O1 z2q}5}5e!a}kJi)8gpYlYr~)5<)EO3?(~s3pLYw5xb1}=!5VoGZ=VI~&o0BTGf`0#K z7$ngf3pb|!nz5kOylq&{Z} z>CWTqu4*p(+$Fx~9f)^3{bi)qN6bfD%U##tT3i1av-Pjysrl-Sb7kW_ftFGIJIhQx ziSJR8`ag@_M$VPjo3|@PZyjd~U!tVmhJ%yTTZuVlqPMA#sDj=O-6~?p=_ejS<(=Nr z^lJ3Rp=MNm(V>Ny-tJGel;xQ(5$#rD{%iFPVK!gH=T4`}WiUOVx0^BB(ptqd%Dfsnm z=Lv11+^^^eHP!bkrio&x>sM_5MV^m1Ckh`45K@wlG;or9Y@BZ zK7663dOp^PVyNTe^g?+){A*J9$bgWNeAq1znwR9`1S~iCajTjO^NkO02&K%&5~!)3 zk0YWO>iBS6D$j>^WeOh-i-Z=Gsc+TIgJlHrDmNuhCsBpwS&VQCnB8N`3;;CE}Kz#-8a!UK=%gQy6>3QnK}Lm`&E7I<*w`475*eoH3iM zAHBXI7XQpN{Fzg1os!ry-pKX4Cf$_H$7ZR}61g%iLH3`r^plpYkk^%#c3uvEG$nPl z1e~O<8Z8s{&E$2p2@+K}FKg|)Fh4j)dg>G73};eicx-#0?s@W^JJa;_c+a5yu2h`jPF|q8{7mXcBYmzw;gzL&806?Yl5&xzHwg*H3a-AwZuy&*7`u(vI$<_hzgyvLn7`1PmzZsjQZf6~Z*wu5+}`9uDOi4I7dTM0)>2nn zc6)Q6W%93|^l24EZ#5|Au|!B!Qg0dHB=xp!rJ3l>I!H)VL2o{bMjFSp>0n%YvX*i3 zlt#wpOS>B@6&z+q}po76{Rn-!RU`cK<2`_YyinEi9w zG|VQq*W%wjSbjGOSWwT6tFF7qZZ8E|Cja#2xK>_oskG-4`K%VcL`l8*f|Jx+={07e zx7m=Wg5GjtTp|oYDfcT9p{DwNh0R)_-T4^m`W0o?$@3A^nQ}Z1fRK`WECDCUN26cO zgpW;-r~)6}rF>83^z$4-HOcb)D$8%jB7|zIcz)HNzX>h8SMs@4{Fe9<3V%`GTKF6Y zF=mV6ZRzuiwcqR$kMU+%->D3J{V~O4;}=~g>&=Aw-yl&1?)Qu>!Q}Mw2|{(r!o4lf$*AC7 z?)Tj_gN2qaSpXs1PNRNeCr=LW8a8=YTfd3JCXePLd@DRB2%({&@^cD&;cEPg%~|MM z?!j!dKNhp~;pM4w80gVzY|aI_e8KI$*Xa5Q3BuwbO&MxDW=#>l!VW0t5cx%DQ0i3;a!=Ku z$9FX-;H(A(#b{8-ZVf8`n+9(HVazWrVs zahr^1xeVXF$Zx+%XsP_wp;xH94zGe4Xa;Ml?CQs$%X z*6-z`53H%4kNMl>`G{yiIer|6kdk~{0Vm1F%xz}E$74t|ANa7{F0_dSd&}O$w&4$#3tmXI{jy)3;q^8@Im49^L<(ov`W!`!4Ab`=k3kcHNs;*0n%9 zd%i&u>j$Co_B!vkox%=fufKIvvlbg$6<-JOW$|!)thcmdL2PW*uY5VoJ{~#@v&rp^ zEpQWihTN0eEwK1M9;Cn9=6v~^*fZ)be5B76E&sy{+rBuTuh3HYd!4s-H${g!iVlZ| z316(F4rhRq)M2${Q~&<&Ot0m?GXLmSGqbubVxF9t z#k6XmXBOUA$UHq7#0=`XimBLq8N4e-~9m8_$S#(7;?=ibj{VUXGQSN@W9E(?} zH2!Q#GT!sw3&`%@LTIV{)uH2lc^!JUr06gi(v{Sq#U9~XCv~_RmYaNktK42;2NZNT z_>mVE)x8~8zD;{BB&Hp={9#+}?1;8p+p%8UPZwFPVK*K3&c}=URH-fJi-!gw-z;U^`}qJ}iUj#&6DI z%qDfQyrexA@9?ydn0>K&8QEvv@uiv}9gF`oemymw!^-8@_Qm=#-pe|6aMfV>WE zYf*F<0O?BVa0xg`9X5&(_R-{ZxCs(f&|z+jd&EL0<$jCB0ipHO_ggfuruu&Ez=QI9 z#I>gIu^K{3@(~VBl8+vdX2OR75>?=XiPA^q^z#%#Df8ic@O$~_25YM4!|zXdK2keT z_=tp%l6;&6C&|a8LuSIqT}V`ck4e|;n4EsJhlMt2o@E~K+iT(wLiJV7BU=6`Y%xl5 z4xQf`Un1ZyU$8mw<@@ltf)OFOP1X;+iTk|=;&THt6@F9vXeK__(8dwBMe&Bfp7Cv! zW&B3mT;loj%sKVU`99Kzm08E+^$^sKqK6nrO;QgD;3V}h?}(Y`;Uy%hpa!D$e=C&Rjj^#)XPZ7>{?Z+;dUPOF;D`C!f{hqsV+usJa$@K>s@q0>w`r@{z{zTZb zywgL-33)weY1a=|AT>!nB!iRG!0E)$eSj{=c*C{Wh^aFGJZUE4Hwm zcWq(YEZ@c+tF(hXe_#*0WawTt1BJ2aY2j?$V>{V9`cSs%q|NM62$lQq(};`_b|QQ4 zb2@hDne5maU+TQugpJKLIe7ycb6>KS!|aPw*JAaLZ7+e1okozRu!H zxBd8U1hpGl$<7hjoD%l@yWXdvs=qSujJ$sQyHbv?0g$5P@pTC}N&PfBE$o-c>t_=r zs&M{&(d&!Hf#YvH;w|5JJP3T_krMgAqfJ)}&w#B3Jss~9^ql&jsOQ7MB|VKhD|%+s ztmL^opp@sBTlSu7?%8@S8dbn^cb_jF?;%v~>nH6mHTr4O{#_KUU-IMmuvTLK8+{@+ z_T6>)In0h}uobHxy~`TYQ{!&9zLJj>!Th9tY(|A)`Zl(2kJ;k--Ol8fenS3{*H2t~ zihd#?MM?df1t+PWNq?J(e(pk|3i>JUt7qO+oXcqI&Sh3O&1L@nN6$39I)~XkdJeOp z=N!h(dNwn@=Pagt+BBxq>}gDwQZt!u6@Oy-x0%T-v(_^OeD#c5?Ek;(+pyDr z6YJ!J@h|3)FHQf7$Mp5ZSPJ8J_AeHg-Gw=a)$eQB81w(#=?G@q#yev+8UN=d_?+?& zA$nQ8t%N<#`}5DqbMpFey6+b|!~&rn-$v#NuoK3PZ#^Yo>Zl(4uBAbWlKQbcD|~aL zeh$KNlRy7dJ}2yef_`#ie4ssqQog=ctFYYU`S7@qEj~Ox_=V;4GX_E_^RX3bs^{a9D26&dK3$UMqQD5 z9l=TRkq*mEo{zzovc<=$bO$DRvaepD+le%ts>BRL_Ua6`|ev80z?Fc}<>=p&69pM*xJB zJijafC&@>nt7gK-CP-9)kKDNah=owfd{|r)T2DP68dy_39|Ld5^WpS?!pCX|Dal7T zI7vQwTsIRw43KC(@bMHvDf8ic<9qq&25YM4V^+L8A49Dv=a)zbDaprKaFTpXx@jhS z+=WE*fsbPGLYpY_p@W+0j~^37G1Q%3LK5Wpa4JdR;|he7A`s%T1mSkGuKC#~28u%*R%! zsh*EZq8RG<_;g>MkNX8Ee7N4D@X-;RBp>Op+~oNfd_S9fn$Dcsmd>~br!&jerZd$Sq%&{krZfEdogWKrk~hyO@BKvBdiI`E zep|C%mQB9wpV$~<-@1sFs=cF;zhd=Q*<8cy`7bT8doFxh+{FBR5o_f)w}+UPo`sde z=A1A4mcVTB`bVH8a^*SYq|UPF%JG@JuDCChev-pe;R}=0l`A+&UEPM|CVw7l`=79P z3c8vQX=SLi-^!2>X=Ql1#L5usVP*KYvz0*?Yh@_1%E}P6kg*bbrcMpyfi)#yshAz#jHy@j1)NPojgo2WV*m+pz_ z!o126R&UcOlS#3U6J?sks6Y+v*@bj z3wd2R6{DQ50w7IET`d78sjEiMg?%%5U2TFy6?By=^B)jOx&L7CLTEkp{Ra)K$;VLF ze;Ak|&xgJ!g^$$`Qj(8waFTrVcxfhl7$DJn;NvNTQs%=s<$L+)25YM4W7aEqKJJ&G z@DT|iCHXiDPLhvFsb<2*T}U(^_$c;DXcJ{VbWl_M@nfPWhPva&$=C9Hgwn>huRusi zK9a#n^06k(O!)W$i7N2%Au5C2=klCQDs!0~aONs|uv;?Qc5wz67@CHw3!zIdIxi1{DRK-haJ?&<08eCjt0f0kP3gX!4)vp+qJmCbiQ z?78auW96>dGM8t$KCAy;UO&i^a(uOWBYZiM`l$;}Qa@K=xyfIjdAt?&PC-Af_V$R* zxH>Spw(s=lFS|XX^|cop0)AL!2tBtr+Vwy8=;3z;dmLPQ&GSrvp6MF1hS|KX5_7J> zG0(CSr$?7=#znjB>k%Caq4IA0?)W=lXRuX~=BK_>5V;JY8 z|5)dZ*!lw|+h98D7>mEJX4B|~n4jF zZ=tU!;|zh2s-)h6!Aa_^^#@`9OkQvMAW;Rq)r++@7CmQatTC*BvA@2k@!XfP#-^Lg z8*i0D#^J+C80YG$8=d;MGKR22jKgYFq^DD_0OUh>;H^wf!RA-4#Mo$KRaPI zxjh}yVA?x())%v#G{Z1ky#6$33B_>+avUM^TtzMy+gZ+I+ds?eiYY=lk0n5wlDbL* zC#kEApUgy8MLr9OD(EUV#u>B_O1Yol3pLgE6V{1hsOu*@M8&>AQyC#-&HvJ8*yOPj zCw%+4PiK7s<+z&xAtm{+`yw`dLe``1*Im@qo;S(aLV`2((Q8>Fr^0 zdA&JZrs&O~nD8Y^>dh6Lq~31Ba+B9v+v39BDd{a2?sN2qP|E#>aHy%i|8P?jLtX!& zkd-_i%qn!?9B3LpKg zD0~EfljNgfNns_E=VJjRnh(d12neOjM>5n@&xgIW(C&N;b$qNXCC|su2NXVLKuF2+ z%W80ve6+AJ6Fzo8q6&Nz3@W5^zEDKxQn8@UW$1f0y!9)#67!Z_WA%aE=9A8L7@NVC zuU1Gmy}7mSaG}z=|BjZ_?fF_v$9a8Z*G#q06$mP%D`qRSN#6CJoJ$E2zOVnZtx*+h zEVhMXCCnzTpSmv{OC3Aj>|6;On;qVM4rVuU8-m&7_Gfp(-~CkF=SONjkK-@N=Ccr5 zCjYMI3YC@Do6~KI-jX3zNxfOv3EwcOx81PZEdZRP-YS+8Rx)|L zEr3K7^tOCiIipQ{Ib)yx<&3}dFKaAuzKpSzwyg2f=(0xiwv2K8+_J_Ov&tEtMcW&z zd6hRF-EVKa>SS+>SY6imwskqCK{iPV}}tJ`&SU{e#Cbo8&u|#h+hC z`hWDqpHH`FV-ZX*mcy=7??dRcd=VCZc`}`QvdpM_~sP_^_y2%aGF#1EG}pm;p7_^RZJDLmeNdtH|@=M4QjE ztR%FcBp=S;B>6Z8%T1n-rj@hB$HeK5Oin+GAXM(XS7~?^A^GgRSBdEqfsNP4IT7Ra z_w6x1c|JsUC&`ZAe=BZB>GKVaO>zIjS+d(Z0(++T9vN~To3}IP-!lL5%XmPsa?)8| z525jt^QnUqMGvmvB=v9`mYcjD+E&e$9#DKc4dPm8P*@EOx>H7jLhUr@sFMbH*Vdr* zwKZsZ6AdcgOoQ|;8sw(Yp!RMWq;0Q3L0%d(y^{vTwbQJHP))MDXUr15soE;$+Xg!e ziSLzs#~8mQzJ$VG)EMEc-zTo{!m(s6sy@H;x}+5K5VkM5w8r51TqdyYn&B z@ln6NJReLFg^vITDcR3h0#1^TMs>}Ek4=!M0v`vK?_|gSxRresvY!3*ND$j-=SsFj zuiw~14>z#Cr)^*lAKA>7=^x5o*%iXR{t&{pei6zxIkJswE47*Ch>g=#@AXi29GoxZ z2M@#i*UN3ewkM8PrM|FddDqWqsgc*i{ks%B1VU<(dI$z5sfX4L%tR0SAW;Q9eBNe^ zc1biuA8vgt+Is4t=vLe1{3*kbnd5YT=m#_xk(A(&mXNhMb#j$69{Ce2aAl8qVZ@!G$RS5H2t!#*GPh4N4`F~qwIqr*_i`Ms`_PaZ~ z%IhICk)nsykeZ|(!of-Ep@-H?^k9HQ74)z^;~G)oK=F5k;8<-wSZFa!6 z$Cpe!dAk0;t@1_>evRezp#P7ehpmvBq#llglhnhAMrNXii;$>-9&+P)`aOhFzMgh% zEVQ2b>**n|ruysYWliPzaJoU^BL+fB@{s^el8<>!%!H4Zkf;J5pEh->ozqYGrb3%2 z^Wg(E)$=h&6eG)VhB{ue$4#D((B~9B5+S4{9~s~z`PkOXO!%;N6B1S6+kIkYO>i9VCF3*Qk3WX1g=0Xcf^5FnZl8;lc+~mh=T->w8$3N+3!gKoR z3!#+xSPeDR^ARnIp^lH|E#>(@wCi!_78E|*!AbIw1j|jHkFG7V#Yb*je@ur^%6vpZ zP4#@-6U9)+hn1&1A5O0+#}8dA3LpK!N%B$9Ls-e=`IrESDx6<(gOBwPN|}!kZ3;eaTG!+^N|KM)$>t>722JTp^lHv zt>yU`no8j#5JE~`e*}Y*>-^ zo{zN^LQ3*+9GoN{BfQLnkBg9KKJf7#LMij%+U9%t7y@gm=VMtr3LkGN$B!5YDal6y zI7vR{wKWqyUP7Yzz(@IZLYpY_;R7|*A3x@ZVyHX6?CBuS2S@AQCPGL_J~F^b^0BSG znebuVK}b}QkDR}+$PGd%^AP|w)$_4g6hj>!g}TV|5m%1#oH&b)LJLar;Q&sOk5jPR zq-^v60887cZUROhJQqIf$ zyHIo$08Ua@6}t*6nY^wRK%xrA-JLt`Gdca-hfulye7%HjLThL5`Fc(@>QSGw#T`0= zG0*)~jQSieZpI?q-)JsoGmVyEwpat-%ArHJMxLI-ZLXJWzRkRaJy-R7J$`;he9wdU z-iXZQS)N}yzlXejyi0dJIm7~?9^dY`D8N6x^4o(ed+@s#3@J*UmmSsWAGtti( zNK`>Ted~1g$mz$)=l|a|ejh|hfg{vd#qSTq_X|1nP@^Ax9WBl$c~0oN6F&z%FM;Wa ztj}Fqj`?jpw_rB+@BwC%>!Zsxv3%m3%3*e~Kc-=}c>QUx=XtN6?Y-pnV_TD=p9Dxz zQa@?nB=xhgrh?&fULU%lBapC+(8AMSXwBOXp+IS7^e{hQ+hg`LP=|7K#h8QAX^#Me7~IS^79d#={f zSM4yHtbeuE-Z)K81S!hV^&es(~j3fE`OH`f}PZZR6ZF1}_M=JDR}pZizC@P?NR z*FUc}Z1q26*jm;(dfnqb(akCji!Rb)UUc(8o1)j+uZ+HXzhLy=wf`~vdvmS9YKYJ# zU9$YX+V&e02r=K;zY+I!nhq7Blq`UdZKqK`v6CkUcnzC8tgYX~VUtJm5xy0;hcW8z zOYGk4kr&Qmc5=htF`F;q@v&bbJ+XVmNk2CVf5z9T9nY|PyKS7hVfMQXE||UY>~72^ zw;y<^9`;)z`vNYQJ$Gs!+59#`OYz@FmUEH#D-n+$sQsTGZ@@~Sk@7lBb*AXhVwmv7 zO6t%7oTLsIWktQ{V(^dOga~{ z%GUV#MK$B}r>%@r-P#!+ylZTH__?03>U?DEFd>QC*ZM8D3_|76`1c55N3uEoP3Y-V zy}zlvyKV@=_$Jps^zsY#TfSCrDr4uK28HWlwpSngw}9mKS~ok7#j}a@!p?rOy0WcD(N+JE6kP>?lhjqkQNl_lud4-+sDiF?WBefk zLMitjlA)&h{)7E!q22iyS&rFoPLqC)g5y|uKD4$JK4w5j$>Z*7aFTqq_`yv0*a3+u z@KJkz+m<=~yoOM@^L!b@7@>u;`Fxq6diXr!`fa%FadKzuxI4)sK+B ztlws=uqS!*e3|-w^4$B^rEnhrX-RUw1e_%IjeO07`%RFj0{3Av8#6imq(Z1%{Qdtp zp_Q}u`%ZKUpTp(~7slt?#vGQNKj4dgs|9_2Pv?UBV=d_O89yDA^;hu|_AE!g|L4yG znb#CNpjc@+QC<&mB`A6bgw!PU5DZRI53R?Wi5~Vrq6&IId#$vnTrn-O`l>;l?rBhk z1Pwa#QG+51Y0;;DHKA3&X8QEk1x6(Zb zuP=(HnfU*<%5uFUZZ4^7=S&Sy^)T>9c|Ca7qUd2Yq$a6{aBz}(=;3cBdN4quN_xnJ z`}LkeDCO&B=O2aEQ-9su4c1hD-8^fOJRjQX6h0y$q$D3_!AbHlDZotlxC@Eq10TgE z32maxhYo70=VPKMMwa6YwOjp>R zR-U%kxt_7r`9rAO>wk2dE+n75>#a3?Zee4RHS2W8#vq?QD1q7H>mR;+`l++*7$aX? zjEgb{4EsLLoMwirs12{=N zoPy;huLqYI+0w%w@7i zA3JcPzI5OoRO!sUFVU4-XWNn6*q}2P_^v&thfukvhyF9w=%J`_1jeJI(+A8RckK*j zi}~cs^-rIvb8>fHRl?>F+{%2xp070U->D}vdFRVamr1hQ+Yft|cX~KKo1%wGl=Fk# zEQ%iLf|Jz4RakEFdhqx;TY5NYU!NN|zXtcKwgUI3TLJD%r;O-rhH_ksNGI-VJ;b#; zY0V{CXt{qQ8gk`NHRMKIZ^ivrvNJb#V?*xlHV-bzzCITOp>j_TzO&Wn;g7$TV{^3o zDi*_z-?cj)!Tfv?^PAYEFm`?+{ntk|!u;Lq+GF}SV0!_3URkwnpHvbHIzQ503WoC{WVrA_D zdH%FzDg4Di3X<2a3E(98n>XJ~_~Cd#B%R%wmGCileMkCyZ0Km}_H6%h#wbYXjMCr?QIf+tdAF z^XXb}`bF0N17yy(K^E4<%^=6RcsW+qE|uro)}C@6I14FB@|_4ylJBKUgm1v)`F;zD zD)F5Q^F~ffg*H*XPVEmh)nBJB6vfEG4}Tow3(p9j1Xd0$m*+!Uhr&lPgp}mNVwted zBp}n`M?JQp_KWU0X5b0u~QU79Us?LQuuJ7@L{<^XhBInoWV)*aSoQ7 zJReP0<{KYFA(S#7!BA5@AAgHtsN=(HjXWQ5E)+iM22uFXfs^Fp87wz>K6_v-NjD5zmF|YB9h&^CxQ*}I>0`ddWdzL62U%C-^>2;+g^5D zuLw5iSOhzK(LQ$6*In#U2$gs5v%a!g*qP6g*Htaye3B|UuZXX!X5Frcjgw#cS`T|~ z$JF-cF}udqY1p_TU&Pyc8g`vJ&bYI0Yiu0xQ@?q#qEcE>&?49MQ_27s^sxF5}c&o2CNnK&*b%X1`<^`U#Gu{@mRLZ=yAZ-=n?1| z<5BqU7?0f-&UpCE{l}wo=~$0S=VLtr4xIBSS}E4U!TF5GLyK6Ckmdh)6dW4s5x(q< z$Dmg+9<_h{|96hx7iaU04TN|_(E9L7KHYC>^mg>OVc591m`}cZp4z3ASU;`e<1o8H zdiP%V4q^FEe&;N^y`9i9`KPz)!SZ?wYCzGO zFuI7z*ogXJc#x2Efby;IQJyFG8XXRls!M;E=}1_iz09DaSnCH?)5yHNcD zw|V({u6f*h?hj1{w`l5nZvU`%Ttv%vT)A=Yx#er#bDg%li1PLkCVU%FfE z!?wql%;SZ9u+TF3r#G((`yk1CYoaWI6Gi9UlU7io`h7>+BAfzN8cH4yJCHXi3%T50JqvrN(@sS(XAKnm3 znU5tF?%GgwnSA0ziu_-I7oBN#$T z@(~G6l8*uV%!H3KkZ3;ekqV)d`KY`9d->=CYpUmC{sDPDB1%&DI1V8t`M3g3l8>1Y zX2Qo~NK}!JoWIw{_JGhP%6xQ$n(B`q(?l`UonN*el;^{{1%;0U2r0=&8aPQlHb$BW zA4Ludi7N0>?`Z)hrynhZQs%=KYO3dBohXJnK29H&=Odykg^vsfDanW3A)$FmK2E@L zlfOQ#c{p2qpo!N!bNcayP|AEPftu?1I3kLnj*o{&#66X8LX+Ej}W6gAKq;!d;~*CNj@UMN%Aou+D!O31Boi|QKw=nHanlX z6&m}5MOSH%rlhVcV}x&$)YU;)Zt~~l%BO@KP|(%w6|PKz z=yOZ-Kfj!}#h=W&H&?ha@he;ze*O6nDsSIAvhTF8L)m-p$kE9!0{ z=9e#jRtTW#!S(lTm>zGZy})dPw*j-s?bq4-6Q)1X-yp={h*)o=zvA#hvih_COK7S5 zeecM~Sa}_$cBANU2Ba&g!`0vs=$YBi!mNK{q%)Ux%V79*9$`O*?Z2ZzJMeCUIn5LfSjt~&&Zj63b&o3 zahq6Qzk8AFb3VS6r|0nJh#V>^yS;_5XW#W4yUb&x`1r{Kik0Va@_MjsLOEV0Lu!(G zu(&9EBcvX7!*Y|q-Y9n|TYA{LtuK?)&twRdH~s0^al(#duRqNdj-zX%d+kYYWuN!-t=RvLZ-3ijY+_Qpyzh`QBe1NNI#$f(%-6&`WD!S z;tl(df5H7|y2XBU-*P{CUvxiO9lKBe_0~Q#@#8+^-*i9v)oVXG)o?$GwcCFlLgkIF zZd_HRs}1Go+!`w4y4V$s*<9Q)%+A7nY#@G4A#}%`G+^hX>5+@E?RnpukJ(w)=iG5! zinibEn$QyYqpOiO1+~1T6p_H%h>)sGr zPyO|MA6QfU{J{Kpc|L6WQusIyAtm{^0#1^TnK#XZkH?T`KJZ~1FSLm=A045ldOoI! zVyNr?ZBLNrBZ79ln*bpt`A7pN$;ZZ9X2M621R>FU;6n?cl=<+5n(FyjCyJqtk5B)~ z^Wooza{S1Ekdl1Z-4>dc6rhs(37?3sEDbKq6W=xJAthSAj?dk)xj zl5ss!g0<*n$@VQ=j&*rmie0oSmYEUyFEf}e#Kw*t#QN=@$?h%Fi>?2xDmx!S<;`{5 zihqS2$zFfxkGsyNu>Onax`!_f#}&ZdQBv3aBxbu7jl*nmeZN9SWS=d?m)Wr?*t4)6 z4Y`DEZ@|lYm`!f~L$@&5cebQJOXSaWTh9j+UA3p^%IB`|g-Pnl7o4Q7O5YP!GI?Fi zhC~&PyXU;Oa`iWzobFT_q;Oe>W=2pzx%6X)3<*p6c%C*|Hl{+1A3m zTYJnVxBug+N3zF-&CnA0qpS0e<#pxVk)kV$N5U5-sVfI?lDawt%T4}#kAI|W_k z#yCS?2&LRlSPeDR_Y$6T3;3#enh`p)jM za}^UIGk)K)a4Fus%zOGW|7Olf@JAo4OnxrUtCsd$iYt(c&P1RQ5Rs7u8a?gdW?UiJg-x6O!;V)k>cJ;qw^8ut^ zf7V}?O}^+KI#Ah0t0&|02@a!hTa?cauqS-GWMN(0G?|QN{>@~ahcEMg-iH;x6nXCb zJt*h#vyhe~_le*nxnKIiOt^mwi7If9V*b$}^hAT~j2aXeqd^xhXwdo)4GOuSK{JYK z(Wbi^#27UC_NO)IP^1R!{9A+025XRZuLh+a(x9XNXuMwLCim7UIpTikTk#<^vyY5K5Vk0H~>+kIkYO>i9VShQfz0g%69@LJLar;Q&sOk5jPRG1T#~=e;~1wm(q#aDGeS!yTL?A4#y>F;}QUO*vt>X=}MF~z83k~fJT z`rzV9^C&T{--hKhf?X}dB)$eNuncKoo(V<%2%Jtbi3sLnxcDSC*3 z)Fkzg08Ua5^S+vi9$rGC3VO(u{x2&2?dws#e)WNx>aSnth+?R`ezlP2BZ79HXd;A^ z@rE)&`DEKlBTuJj03rhKX+!6SY$44m}aXw;L#}{=K1|Pm)#C%v* zWQ)N>RX{4d6fia|A+u1=0o#8GvQ-D zbX1a$g3mv$fh%b~%2(&3C!Y^5s41The_L@r0tYkpA5q|v%10s?F&{%~m0&`~4s z@djK;^Wkj!xqJ+Qn)3MwwPWxxmcd5~xTNxN1B{rDc{R<1kLS=)Bk)nhj*p2nA3mUz zzyFvc@FDN`@}Z76A2CB1eB1+%QvdhTI{e1`OMOR@Yn@xN;rF@U{~(^1s}xj2 zCw!i+^v$7!om+(VnbWNZ{q)LyL^-kSTB6)GXd6++?cJKUiTQlp65kih`i1+~7JYv2 zFNh2m`#gCg48Q*QI_@`q22W_if9H7~&%c3qzBx^2q-@I(9OAbR$H#+ zzuNoN=IF8#dg~6}UaO4kJyp51;}cyLxcYke_O8C1e6zRrA^7~~$1tM&o8khK|Jg}1 z34Qv_b3}Q-kz&O2*Z;bdBg#16s%$LHd>;1VmI2KA%?7R(tv{#%9~tB2+eruUdeDmCA3fDz~0yoP3yZ_lBl68W~RaJ(k9aJ=U4!tt77MdCHZi^OY+!0+tB@tW0z z<273><255J;x$PE^dBq-3%0I8TD)5nKe#EiCE!6j_3pZi#!Fq4jy)lCiA24D*-otv6=VOFZ zKKUs45(ciM`8W$o`Fy+<_>jj(?WW>FxRU1MF(~EpQMoA}cg}}AK3cno^N}&0aeSEpE~&?ta4=#%S~fEiK6XM!CHW}$ zk^!!y`LJ@~qbHw_=1@~UAH$l9^AR?h!AAtRr1B99M$AV)S2N+`6m(RQkAmM9$p%-_ zd^BwSxqS47n)3OW-$I-Z@2Lzv62T>vk4!LPK4!X^2_FxkqekGvx&rH-sTDMic_~;U6p$sbV&gi3EAFEuI=-wBv~w+2z> z7U8uYi&@_i*Lksh|HVnn`iX;fi`FmZ#Ye_?*J#BiHOnoz*(1y14f*0n>1#UZ$(@49hJzpR&U}o@7~5~(mup#X6D9ebh&Yw zn;+veZ*t=_-WKs1x5Dun%OdfbVuj;1%L~VAyb8x_?r`@~?#5{ASpB^T?l-3jljmb#=X~;^_)$^7pT*!x znvWDv%ID)Rfe(3nRPz?+!+S1+51%d!KE{9%^HHHIU&-Y8m<=73JiZkCzQt~ECC$e@ zP|D|{tT!Kb&WAicJbc9Y2n%8G5d)` zXbd&w^U=SDI3I!Y8GM9;ODZ3Gz=-+i-rY?2H~}3s0v~^ZD``ILdVDS)U7@CYKGJ%N z^WlAs?3n?ah10-+hZaWh04eJG$*th;rAKC5bY=Ruf)NK|J%iD)M{c zK1Y$n)kN9qn?*#q`m0VvxpmMb;u+UHZkLGmvHupG>Jt5X`(ZCsI*ELH^*ly98T3hf5i?Q zR+T9KV_k+Qd&gWQ?n9IcA>Y?{bEhA1Uj+N_zGOeqzm2mu5M`mhaX&sX#>=;T1I6>r zDS?r1;m}oTzU=`c&bRLU`Rz0Ld^-UhmB_aWig-;4MZ9KSZk#6PW1J@PW1J@XW1OZ( zZk*<2Zk(p3B3|=XZk%REZk%R8Zk%RLZk#45H%?Pl5wEdP#A~?vwgdhfbMpT@3tyPi zzkB#OzugDQ$+tc^H|75I>My`sl3aXtb!GWf6?%;3Wv zjF^x6u-@eP=rSZGZ*D!eu3G2| zWrffeO3Tm}%3`4}l+{CDC{>{^l=0xIbDsCdtv~HM6bfYl-yi4p;kSqK8&tZGLSfx; z_;l5zNkOd#Pa53TfBfJ{BRCJA7H<9wi*O%ycjSVj!t%G{E*=qALosblnwAy6#Zxblu1{>AE>>(sgfJr|Vv|PS=IDN!Oii zldkhY;`L1jIpC%;=nP2O9 zjwtV}Vt-6%zZ2y_lpkvr5qe>ca7*qO2hkkjmX_^K6ZN$Xe;~@-qW6CoB4fOHQM0k) z`4;mdBj0RB@q6YJk~7-qC1eIS#m~uaPb*!zeQ)XcNd(|?p$z2o3ZeW_R_*L+KCI!XfMt`qg^!bj5d1y8SQRx z_4V>CWsIDBi+Eu{@V~y-5`tIzg$c=BV)XL>oJazZxM`qTMAvJ=35jPalUo*=eN(~ z^DO~7Dv@tr;yfe^TuGmY*o@<&C;vR89n_S6-(%8v1|M+@KK6i1Djz9e#C(hmFcUt0 zg^n7555;&sCenPkgHk>pBLzP4%&qn39@OsjlP(@Eld1RiGa@fciE`LGD$w;A)X7uK8n@ukv4egh=< z*csYb-8!zYdR*2a)rRNGRbItHR4FgRREokoRgcT2sWQ_FtAkcnSC6f0r{1umth(Qu zvg#*G>#FU78ml$ez0@!FG*(XnS6}BlL9-|E8x@%S+(W~agV5bxu=9a{M>P(EUbSA zA|dNLL1Nb;@N@Th?vJ*fCZ1Q>n;3bep3DyzHLrZZi1W&F3SY_O^C|#3Dv?*&onCA2 zl&r1m7jj+O{lgCJg5%4z7kVz$?)`SScI?A8+SM0IXm6{NPV79g??gh8P*10=eqP;2 zpYu|m+TmrhU{kB$ayPYU;Ogt-)vr_KRnyd?eOyw@I5$sS73G#X&{XE!%Xz3%Rm zT7L!~ldpIEK|PcAkiYAFnB68H%M$Ef8`Fg-zYg3_l#idYBiMf5%!?>jxZa2;2lXpP zltWIGBid6R?Mv9_c4U?&K zLkC0LCmh`DzOa9s`|oW>yMGwCH_^?Z;;}Nj<|Z!AZ0bI=VYvGdaP{@}$C<(W#^i5* zJh({&as78pl?%l6;UB+CCCYObS}>mzIS|m7crK*R(`H0@WpDyK4&>f685AVZzlh4C03;C^+ z$iwlomwH(B+2Ub4ZKKDypO$&-wH)JdrJjdJl_!-w8n>?R(WFuvkI>GoJVwna?a?<_ z)6)BFxcl>$x$YgjgIf0d)ziau$x@GaaP@Wb@b;pD368MnEhex z-=NPs-%471nYd;zFj0Q$Gnpt0=TY3!J-8fk-xb?O)&EHN>*173wC9&# z-CF;QsD2TatKa^fX#Z*jyOTn@Pt#^ZS?IrUI3FqF&hz%I70<)KSVkU(LwBipxCe|l z54*4Cx6$PD@C0;JVn2Oj!5wY2<5s$4bxY;+R+X_SDkWy3Uc=+U1SHl^2Fss8(-nvd z$hY$=yD96>^H%n2+f6xQtB>-|fv(D(C)z1%#k5lXuwJcv+WR|Y?~HcJk2T$uW7=3K zFK*lC74Rg(>)(r3%EUVDmHp>+Q?3D5U-!6oVgtWHpLg7=`tt|T>jB)NsaA{l)^m}M z3yHFjac=qLGWpyBw!7^qLDZi$EQHAEM-7e1+JvePi!{v(UX6E z(hh2JKIEOB%-Sl>N7!BlAA7(hm5&rKVm`)hHWNO6g^o(_k-l$!;_7m16F05>=}4J3 zgwPU-&${N`tj>bO(M3EG_udXqtpCl%MAhw$iMOLSxmzl(x%V32ljwcH zDRFZDp@|M#_?WcH^B!ucPx}vr!s#>KL#?!xZ}mL&e;0Eta*GarbBl2Per~avxQ-jy zC7LL2J9ts_9T#qCI$y`UPHb^@8F3HSW_W4ho-giC{Z#Sm*5hGIx%lN_Ul>9>x6zkr za~uv_VoBOAo+lYmj6BJN?ospPF&J^4tlnlOdGZlDDv>A0Z0*&L8rZ9sxY?_pc-pH= zs_oU2TidIPw6s_EuV$})U~R8%Q{7&DvZlRyfStX1yNA8{v75bmVjX+6vaY?lQ7wCQ zpGZC?syum88b+$wXXFX@j<(NszU5ogT;W>fmJIm)^Ws=y&T?k?7NXoHsti$X6!1jP>8yd{4Ar`Au(T`?nhJBJPC>+dBYT&c!rO?g+!G&lT2h zVIFbsk`T*-9pd@p#LA!YQT*Ug^QR#gasFI_^(H?L@r>rTP9lFak(G{T7r&HrF>yiC z_@`}Kc9?#^V`%#*kHb9&wzT};#H3oCcO}($wj}A=p;bv~w^t|idZ0P}bI{P^7dzHI zZokX^c<#oU$Jc&s-HhXm z`wxsf@c|>wllQRRic-Le-!5< zgY_LR-(3tog20IR_;xp6$>jN12pyH!kA4Y0V!)L&ACEyPpO4Bv@^P1cKG%A$I3L!m z?<>pzm(=5II2bV>E%%rSA3LF=M&Kg@TuJj`wU>{cd_I~(P5FGx-_PKK^}crmxTNwC z3r5UGzkO!H$0_Kj1Rrmochmj*KUZDL&9`(Zv$J&r`eo?0)+mwu;)i9rRhIKrn@^lp zt*Jg=wPn;C*e~QNN9hJx*2W5nA z{i98~Om&j(P1%LIO|whrZ09)Wc6g7}bv<`UTfJWmZL_p;x}bo%x{YyHwIOb`l1t|{ zPM(^vS69sGoNjcJcwK*R^<~dv+8*RLAb;mEkt^2{_Yp9=8!Pz{>|%T7qXW$Q3|=8k znf060{F7Nf;^<1zT;2v-TA=e7eeUSbXE<<)rP?9!JhA?jktY_h{6J9i#0HEwPf}sM z$=doab0X|f@jXO%E}+h{_Z({ z;1sWhbu5$zrUonLjybHH?jEQ7yX+q2g1~5H7`Xa+_uKcx^Ba@D`|Vd!(+DP?b$&*a z9l~A{Wo{83pYD6?C*Da`x>h5O2g5GDVdhNXUMGlqb!xljg#P9O@_WzN|HLk5h@9_n zdPMDBP08MyFRbD-}>AVuG9aW=eXo?SUlgne_-TW5OkHAZ%e_5^Q~zDzkMd3 zZ(E_G633-4ab9=^TuIOSEe`Y1lRxio3^nD?`-dfp^AUE7!ACf_r1G%`jF^w^N6dte z6VOo!KAPS=oshfebVAL{(+M{BPbcJDJe`oc@aKg2_f99&y>~i6>2@YT^XPPfRo3Z* z=&aKTL++kV74b_$`Ivm!dCNy=HGlIK;XaC6(k?ZO7w%)R zU0YPujAef~ODQK1#St3-`pbP@Z94)uEH|5M=p3xaE$E=@6L^h`oaHm zBFX}PHIDzcy?MA6ZnE&4l{^0H%iQ02?zeg9#5uOU$>2Byx{LcRghSV;`LG9!I3Kzvn@K*LfR0M!!z857F<&KI15J1$HY`K;o~-R)ChbOKgq{Lnh!N7vYkpnKNd{~|4w;A&h2kTA#`b+gQ{02zykuuy)HOt>lwRf1Eiu*fkxSgu+ zApUQz96H=i^$pm#vi@h>5Ia?pA735@t_pVEQ05oD!=HEF@bAM=;<;9C5zcv|AH5398E2I2KY4k&JamuH^TI!&D8>@y6G6QMg)jx)iC zIi7izkG9Ek{17@S!SVA;$4-P?KXziqe=TV3Co1DyOWYC(zqv)o_>SWxL>c6k z@B2D48LyO3ov?e9wIlZL*x&iw&7%GqU-&OBd6*Z5M$fwbx1M#bEPnobQJnk0I}Gl_ zp<7h$_ka;|-#x=jxIY0MmEiu1od1F=>GK=Ai+uFt&tJPj&CfXhy(G?ubryqG%?-g-AypJ;Y z$OM;EJ|2S+^RfD}neg!uIx4|OmW#Ejpg;Amo)6FK`QqbC%s)nfD``HWKq;S(3j!bV`1o*BoDZk#3_hH1 zF!<;IM$E?xSa0%t47_PHJ{E&3X+BawDW8wO1U}^PQSG)kAKvE~eE9sv;A0FJF&`Cf z@s&)TkJ->siQ~(c*njK>SJHgk1EqXE%HHPV&iRnXhewt;AAvU*d<20@>hWbM7%?AB z@0bZ6TcM+pd=z{+1Fod`u*l-0C!deTP*Xl1{qKqMkW38K0-$&`3UwZ=p3Z}!~F6w z1eEgmSSj!!kB_83#reoS!QdkYTvGY4`h(wQ%tsuoH~IN#^*{LykmRG_OM7r7z5fUS zrF=dP2z-gQWWrK6u6S+BMOxA z`M4nPA&-v_PsRDLPGjspoS!iG=m18{#|v0*@_Y<@nlC;MgwA&@=+9zsCCx_)DCP6< zm%xWSKC1mC&PT=t1|L4p7<`NYBj%&RbH0+v^D!GbDtUY<`21rxxRU1M9w_DWQT8uB z?wk*Ke0coL;DdGjGzeT$k1tEXi1}!mZ6QswmzM<%sscVylBJ8qS=LtE@}|J_Zqb4`N!efSaOD?TP)?|Tit|L`92 z_q_&g5k4z-Pi@8gKdHT*XqnG@4x4a>cvh}M`W~YE?BH8w{ghu^3IAPeLWnZ%Z;{)5 ziD#?Z_H`o4LcJCuBl~*|!e^@W&*Ra4b2?)2cqg83Vd;$hvE6Ha5UKg*4n~}B_hG%s z&*!?l;kQmA--f2fYHF{H)il2uruU>y4 z`u!1ZDfGMo@jVs)rR9lo>VQSeZwO7#SWNh@cq)P@NtG5YSN^jw*G@hP8?nK6B`PJhm7aGh3`e{|91bkAo*7MQ9AKIh=sgz zOIGRbqQ?(zdHBN|;$5AOFJ}?u{r-=b_0wlRCH$XhT$K4;Z?BOTi1yE`e!-_ml$^UdjJ#_`SKBR`1Le6s-~&bL%pZ}R!(n9FaSM7|aDUI|yf54e&(-v|e# z{PR(*z=yo+6;BIUeR^4;xRe(+rEshdUTC zANOIs$@9^r5WjU2e3V=CLRZkAY2Zqlk62L3=i`pRhde$?6&B|s`!0hIwFQF@Uoc`m zEG_v;CeKFzbX0;5OHI12pg$YHl{6ojpp?%?uE2*pJ{*dQ^AYow!N-uo3_fOn5%W>2 zh?(%Q0y-+e$HsAIv<3Y+0kNwb52|m8W{Noz9lIEj)aXxzT`S608^7-($66YhVNT;Mh779i8PhTD?#LZ4V zO-#CTQ|c&iN#!FEjF^w1CCr46bm*uN_;>@Zr1@~R`dmH+K~4F5gqC9P@szRuNCB5r zK5l>!^D(caneg!(I%)(ys+8hmBF%>nDCO@z<_LVqJHC7Q~>jPb){G#f3zJxjuTz$Rkw@b_N8}oVhOGdg_ieCTZ zmh&BcBCe+vF7rE4F4z7y;(OKHqQ9QQE${kIC;opz_)_x!EzG*mov`EjIX>@*_V2%r zC;YFw-Iw^jwy^$R5E)RTIjq<^aMh5(mwSKkYSd zyEW1b16OVGd_SkmCq5Jkw*uTp38=(x$TRBqbhwteB@2FYi}09KJgPFmJGSR`Z$;!! z?!{_E8S6X0T0^uq$l)qcF8_2aQO5P34s1!Z-@2rRD6e)YMU;j0FF+)?IOmxg3PVl1 z-!HX}`^E;be5fLxR~eTX$2aH7{D4vOssk8tUcG?zCV#ziV3mC3)t9(lu^3!QpKqjq zQvUhIUjiR_nBth>7V7s`=2sKv!>K4^zw1+#!N(XdVm>O^@RdxSkJ->siT&>1e=T?Y zx$bh;brlx5zP&WXwNCpnuJ_UcU0;@)>srEPzH4RIRj%JJ-{|_|)D5n`E7rKSJQ?Pi z^=P@P|FmVU>!yXeX8*O^^#Qp0%JZLUeB|>t|M}m<(!@8l?-na^Shzp#HNPlP<`$v7 zNp>vpo%{PX2Z?gI>N!MtcxBt>!uq(ql<9Se{^S%LNt9Q`x)Npgd)0|DZZFGXjf$eKO!Ba3b-tq#c{s8{BXvQ4MuDrZcitaT zgWs6^o%hH37bO^d>|d71k(t%Pi1O=?K13Na-|vrQM9wbX)te||y?>b!M2=$n&1Pf{ zUT;k9GqB$Kq@(C}{{Mi;eAanCYfhxUCXna6e^xE=e9OpT%!@kM@`Fgtw;^D}`Bt)~ zndI9P=%_@#rPmH}y&g2mRWqiQtFr0?m+8$Xx=dE8U3^#WbeXlVylasLi(DtI+~s=o z&mUbqT5WZG>lW&2nK;3dxg66N&ei-e^+u_41U}k>D``GL zKq;S(0|FoN`1q}XI3F3T{YUxwd<3a{Gz25&;}Wblc|JTF7>$on;7Xd0C{W7hl=G{?Q$qX3q*VX+V9H+sJ5!c4SeNp;>4KEOXZ%x6%$$)jd*p(Y zli=#>&hwr-@EerBd0x;-N8%pj{_>ZIvhO#F*1~z(q$?{3JDykdXnBFSCtCS>-IK!l zwa(Qf%ARvqGp{e-jP)k`sobX%bn!o~l^K z-m267V^otK4OR_Zpi-6i_>Ib`a2eH(hgDV0!@pIHYh$On9#KuzzA+z@uXlZ8h!gK2 zf7drImLumYTrY*`|sYm zeK|dKzs&8S8{^YW_ixJ%x^1uFd#J8TYt1%T+uNy$dt)Fc!K?&BL=`#CbT;h2KV#&%@i$QHebK64y71 zyYexSK0i@|QvUhLc!3Xj=O>q2i1XpZdS5LQTvGXX3`Wey>gHy`$4BU>1Rv#8wUhd< ztdX?)FT13W33Za{+~|;0t5LP2ft^*y?00WWtl!H!@u=UXW1+q`jwK$ckTh~kyQEgV z>nDxNDxdUi3+E&YuD%-|ldtpK%ZL_y>!0`B%c$TO;@#d2I|qxti_0y3x2-*e`_s*% z6hyiAu)@rDf6sP^KQ62v({&zE-s=1#QO5h?g7SBI_a)z!<{tG}scuU4t;)%6D1tB?1wS2yo!uRhw^ zUcIHMz4}@cd-dOL_UZ<0?bRXe?A1ft*sBM-+N)ocw^wuZlfczip8t688)!RO1|~{9p9=>aAxwY$XrA4 zeQ13cQNDe!G{Lu5u$m|fdFPhRKYJ7T{B!5OiF}KHW<`{HckD)#aeMYhi;3EIK_tHD z@lF5yLZ0*c%WCnw^3G=Dm6eJgFlt`eff47`IaqJhQWs#jF^unu-@eP=+)Y2d<26lX+9D`DW8u&1U}^P zQL&vkAJ%^{_8%SEF!&e(M$AXawtOX%=VJ4)Tjo!yfYqGOfkI#yS`0ast| zeogrfeAM%Izh?Z=!Nfhz=*ZuQaT_?T)U8Uw* z4j6I1ZR%(y`BtD-=+K(r_DZ1`LeDM2YXTJ?c@lXtrd~~E zo?cmFN%+IyAK8svswaq0}5tD3H50~^%O{^54+EmC}_2|h` zl5&cmTT{5G0= z9;QP_C5~fX;=05ea3y_S;oO~%p8WHQK~PivdBwh7;(S=MzOR=8E~$Ln03+sOUJoqZ3+f-;waEb96#*)98fXn?@&WY#W_Wq+N8v`u5QY|IUj} z&^3xqSky5(VL`c_2`Ns|31^+66Lh6_B((3z$K=b;bJV@~mh(5y!TY*e<95Uf=PlSi z?f$-$L6Z zRA(BvYLe$XfeS6S)XwL5f^%QK(_5(L1zaoK5(dAyh2XFK#>PY$+5g=C2l4(Ww(HJX z6Yr*Bd#6j$qWLlhdd|fl&%9n32K~IA`}P3$xBj<&eV+RooBNCNoiUuj_dVzmmG5_8 z#C%8l@*`mKe3$8$FTQ)9s_k0T+tD@K$I*4+LOa)$T^(J=_jGi<-^0;$MY@A);o0`C zqsBP6KHSy7HM*&zYd7~suDz@(y3YO1(beC_(Y3>=+OB@!szn~YKYg}Rp-?#FlW)WK z^ZWCiKThSGYmHlC;CE!bdCn}Z-I^6{%CZOl(wf-sPw3xJ^u1$lxzhOn)1I}xy{NyH zuw`7V^5lUqT>5iXJ@@+GlKGG{P&^;PLK*px16`x$gVg|jL~uUD!FrR=hw20Kl@DKH zKHVN%NzbQ4Kq-GdeL&zN4@Vp;+(P|+%Wr<-eCXbK9v>w3z1i}E_y|(@Xb48k$0b;A z@_cyu8I6xo;7Xd0C{W7hA3o7;Hp&~?n}W)ImzH& zf3A@*ijVYpD*s%I+@gcuS9XsSJ;&viXP&VH|HJR7h+Jv@U_@C+t|NYIaD|K%5i5F*ApEz)K^@$p% zdE11ut55v8?LQq?|0%foGRKF6v3!K{cYOG!@@diiGq+eTSwZl=udE|cexKQj$^Via zTbTS?K5g7g&%1unmy7xHTavHi0|%O(c|GU&H?cGe5a&LoDTDhl&@C$WAz;MZ+mAC7 z?$<#_CAj|*=iNGRB|UF`2TJ+#=6V5q+&Le4_Msdf+(JF??hz=?hf_-iA4|a{m5(Se zVm>;KHxoV*prev}D0V3d_>%>$r1`K34K7v2}uiAplLzLi3`uH*fl=Au5CGa7SkIU1<`3Ur2@L@HT zk06x~J1}BC&cS+<=ficH(fIHKSJHe$fKommrv*Ob@$qs7gAZp09}TB7_)vop^YH}M zn>-)AW*Ci+U~nbPMjN%0v(k+ zz7%|k1Xt30+yJF~K8k(M$DQ*bkB??^#QE@UJxBb$&=_z@J-&p15%Xa`+f4Xa2OTv6 zA3AU)&Br@X%IBlroX_Q>$6RqfGI}!jSPCwwd_;i}^U*QbO!!EEjv9fFEN~^whs|6* zdh+>b2Q}sIKPJs%@ZrngV-L8b@{s~Y%*WUeGvVV`=%^$g1wVgL%=<65C9Z#fQa&Fe z1wP~*U)C%T=Ob`9gO9V|lFG+DFk(KI%{LQ1{(+84@DbKyg=;~7Y!~F04_{Eq=VOt; zhde&w7m4$cJ%qu>V{l33!(t)7&6tn9u-@e7rH7gAX+rF&|H0y~*>@YgxYdD9CkFecfPiCCx`7DCP6=ZBLO-p!N(fkx-N;m8oJn2ne5W9&SIAtQ$t)%_U-R-w~m9$o~E5# z_B@{G5_@EtOX=IbF0-ySaw+?;hReQ7wOmqusNpidOMRF1zI9znh4V4_vd@qH1Fh!o z`O(cjal|{8QyXYS|Gyr$EIF+v{x7ZN^qoYRTlCMjam(wlg+zPbH@`;s!}>NOLW%a? z*Bn5Uh5D|m|BGLqeItH;lzU_%KR-o3xezS#*NNvzU?;{rEEc*)&6BfW#CbAtjhW=h zZRn^(o~%pKDYw`7S=s-DmCEaJ71hk56;vHNyjO0jc3K(n?ve6&4J%db52aLP4!u=w zese~-d(%;6i5JI}Aw7;NJKRrEZcNfCo2~tCoXP7z!a>$QKb_y-)z|T@<}Xj4k7`4F zho#1)j>LCSxJAgl=fX7N|48h$a3;Qcg7r30)sCkkDMw};`)|*M56y3mgR3c9@7ngT&s9eb< zqfTF!GI0}Jj*lPdvgxkcWk-Bvm-|DSxzw-J$L04i{aq%9s$4ENuj=A<;CS)`h%-4dpv2oQBIy*E)q%X-`k(uOYHxJTyo2VRgH=L`-RzSi89v5 zj+;QV*WmXQ!XMTL=guVB`{8~YqAb*JgDw5Kd6KqCJWsq?*99#i_<^A2i47QWo}|Kh zlRs~B+?208`4USXa3wu24+o|EdAU~LBhTD~+kbKk^||b)Tg3SY?8n%T+HGd=;SNU3 z$9-6D@_cmJVl+Ocfh%b~VnHdNk2?Y%^7tqf$>5_KgAesq1|Pm)#C%w8<13jw9|6!& ziR0{-ST=wwX+APRDW8vAfe(3nI7Er_k^LQmk0Fr^K4yRs^HFQNneed!I%)(yj({s^ zK5{@QpN|?*eB3!7^7!bqL!1w59|j*G;F3E3hyWwzLlbQ#eC&sg8i9{%;7Xd0@;mtG z$>+lhYRc!sf2TMfG5r~QM1e~xABkYZd<^};O!!ELjv9fFH{eQ|59ghq%f}$7DW8wf z-Qs*?4`A?-0xqe1+yEoyW8N+^;o~`U)Chc3+0Dm9nhzgP%HMy?5%`dIeA%~0oDb{H z3_k9GODZ4lz=-*X{?SbMD6@y}s1f*Z16R^~1c6dMAKL^z3(rO0{s|#*!{%d!ySy6kNdFR zjA9n;kv}31U`;{D``G*Kq;S( z8gYEwIUn-)=yXV&kL*4SK0?4Hb^Z|nM$CsM-c0z|4;?iEAJ@Q@G#}*;@zImdhZoe8 z&xikEaX!L^GWduBmsCCy!HD@7nqVe;q(euIz{eYKCC!KP;m_q`5Y&{nD0M;~w{%||#W<@2Ex_>jlPQ>{23)+|2kPB8dz2P5X=KCCx+KDua)#>X^p zCCx`HDCP5UN8m#qAEi>n`3P&n*ng;X3_g6pi21Ng<|~;z9|6!&BOG5gfGcS}GC?Vy zk6eKdd3-pW6z3zOErX9CDGWYlfD!XiE7eT+SOFb10v|`fl{6nYpp?%?jgx%bIUn-) z=yXb)5AOvGK0?4Hb^Z|nM$CuiXEWhrKXlXxd|U%p(tMOZ#Yay*A6`&XJ|F&P7<{Z` z@DT+rseB}Y5%V$hw3+ac4jnZDA8){wG#}1qK9`R{P*Xl1p=ZVU$OvHYkpeEMeB1yd z=40M3X2QpF=%^9+sB)H%i8LQRpp?J=m?Q8Z@A$GWO`H$w6%0P^flDeM@4$%ph(2c~ ze3VJ!J8A?z+`yGIA3>m$&&M`_4|#l~rHk_sHj2TA#d$u0R6cCLi1|o`^(KG*;+SqU zKKg(wX+FY1DW4Cmz=u3Oo@R*i5jcjyhusARAMRkpeB6iiCeKHg45RTe4O~g{5erKB zeB2TEkjF=^I<)f z!AA(Vq|QGgz=-+K{AwnA?1zpTfsbq8N}7-ISNZ74=fewX%ICxXx;P(U3mJSwflDeM ziD1Nh483M1e56B1jljnna3#%$^Yzc=V-VDo&qwG@1|PE+e58O&Djzq%i20az!%X;i z4jnZDA60JhF_GrO2bA*nA9Dmgt zKHR{SG#^2rl+VXDfe(3nq}>tcBWx;z4~yG;1gU)3fD!YN3hPb&{KfH((fH^CuB7=0 z2c>*Iv;rUU_;`Ak!N*(%A9h&`KHR~G`M3}3O`eY~ca6r!G;k%&M=U7i^KnPuLmnTc z9*Fai5z630eUHJ1FBmZ&miPHeCeKFzbkqpPmkr=bnvYCS%I70j;6olC4iClo2prGg zW5@#rA2Yy+`Ka}~need!I%)(yj({s^K5{@QpN|?3`M7gFd{Do_s#Mpr(92{2z<+5jKvo|A+#YR6Y{Hi1`@$ z$V~W1hmIP7k2l~-nh)p4pUcM}s41V1(5K>jWCt_&NCB5rK5l>!^D*ynDCO@z<_LVqJHG6DF3yK_AcK#4;F8M6J1}BCqMw-wA7!5N9W??UZs1Cq zk04OW=VP0|hde&gvKf5LVDMq_7au_?A2wjbe5As9lRtlP%r+VyeZZA8AK{>s&xcmv zLmnSbbHw?GVew)2H-is%Fk(LL!+MkFqf3s__?QN+r1^*irF=f_2zSG6o+*UNQKX z0Y=P6t$)mfj}_2SBk*wqTuJkh14{XP)OgLuo%11&k4|sJ`3RiH;3EWFQs*BLV8ncA z-k1p=`=O&o;Nu#&lIElQTRwX7`S608^7-(8FV2VcWCkBm;F8KmA{a3rL*JPRAL-Ch zBk=JCTuJlc{Qh(K7z8!t^AY+lgOB+PK2pFXm5&=>#C**AU?zM#hmIP7k1GH2F_GrO z2bA*nA9DmgF_FQ?J#b0o;~f|=AJHGpgpV@0d`FGIha0$(<|7D{^7+^% z@F9byhgRT29v@FF#reo!@nL7d;KLn^n2-Cg-sJh{Vreu! zrhzMIK4L*BpN~5NAM*GpRaBgh7}oq$U6{d#FBmZ&mPPnVCeKFzbkqp@j}72TnvYCS z%I70j;6olC4#ma!aAG|lG^8klj~QUZeAFstCVZ@bjv9fFBj8G!j~r0S=c7h(KJJ_k zd3g4Hz*Wsj%MU&tDvC8I6xV z;7Xd0a8SzULo4thkB_Hy#QBKX$Jl?^)n@SF4o1w!eOPbud~~T}G(M(*D``GrK`Eb) zI|3i__$XChoDc8A3_jF#8GQJH5%XbLkFR9%d;~y8jc|O~0IsC@$ONT)K5_*<za13_fOn5%W>2ftm2J0y=60K8}DZX+Cm5DW8uT4f(ipKIHMy$w8bC>w}E_ zM+ms2&Oai+i22ain+YHLp`%9N;~Kb<=A*m=A3gbectK71eE2(x^Wh!K;3EoLQu#;( zBj#ghBQxP69Xe_RKHh*UX+E4CKbMa|P*Xl1p-$p_IK?ygNCB5rK5l>!^D(cnneg!( zI%)(ysyOj6k>7=8seIUg5%ZA>>rMXr#j%;u_~-+!r1=O3 zrF=fL0w41DcOEjlPbl^j&P$(*B z#{2sZAIiO8*=E{M|H%_aPZ{3Hc4FBRgDez^?llz(#o&O^2X9qvDT()fTu{)49v z4^k9rJ$hoG|KRDJxKj603WY+rLLs^wi{P~UQc^QMAb|Hg@n`5!RfR%PNYmXyp-^<~ z+9@!w#%Zn_o%B_nQf0wulg@vV1#X#ik^7^9JI_DaTJ|j7YS6n=Wy<+THkc}Nia@f( zbXm;APhB!NJwTOZ??bX*>9V6p_AgbYOGL8TEolMKtwyqrRGBUATM$)deF(L-kt*|E zg=9LaEDN{x2UQjsi&`t=LEBQ>a3ph~%5*;=S%0d`X&sWyqsqe8AlV+O%zH1AU8KtV z)*{&(s!Xv1$!fHs1tf4MlC`DEbdg9ljw-X=hGc7~GR1l%J4Thoq$1fpsw_~4WF

wgkVnNd?dce{;qfL4U~s>;A^txE}`7G_Ht43W%bQ8x192D9?ol; z+rKDJ=5p>%x~rHOUEbs?;poIvvU|(qb>0`F1MqEJdQBmt4^SS=mcw}5zD{|5!xV4X z>CxS0%Hv(+yFR*5A((o@*lLLT zBQn}nXY@15vs+}tc--!JFPm!I90ky$yZ=ybLh!3~FxOHZe~e%>w~tb8rgQFA3fJXL zLL~Cm3U+U$5p2%Ea5)TmdZE0>Qywpu)!=a(Q6AzxmdD*l%F~l&66p4YU=~pxF2H;5 z`Kkc+N6z=hsb6z<(0wd3X;W;NbJa@DoyYlcI5%i+Z>2msSAy}ln}Uj5Qr?svCRivb zLaQ^B_h-uUe*#^6cRWoMz#cM+&DqT4qr3AdkEVj3tVYib54(40R zlbRB{$8DW4Y^vdXNTeR!T_9YSH(M!FMdP!Q@(!kliKpPr^b~yxn!)*}$f)La9p&ai zWK?rk?EyCDs0Q9Cr0E;hS_{tG;f$rZ?M`_ZAsEfw!<^5<(v;412<9!y)5<8X=Jr?4 zr(p4D?v5Q>%#1Ft*%#-v?G=2qx8QuRuwi?V>3C8309L~pa?rx$y{6=C&S2_gq6y;_TM*m7B(tb#Jwv}_Y$3v{V zX+12S!zwsApCYf*9-cRvW%yEk2o z3#yys0-gWfd*CB%&So?&^GcgKOrj0vi*T7&b9)Qr=_*8}xtmIP{uETWje-Vt2xc|s zgK#0XlDb!IcNxc~8jg@)JnouO9$b%mI?{y?!E~iOeg@Z^HMe6puPw2A+`S`Qmp8%h z7NB`tNqM)^!-VT(&S;N^Nz{Lor6~9WSHef@%e*76JLwPa~H!L)F(}nBuW+T9_ ztKgQx$Mi7KP`vJYRj=G`kFzu&(?uzsKzx zlt(S)rvg0gwoslm!fM#4Gjr&8mYLvuoEtQ^7f~KHMC_WodxY!qCY|um+8OfTmw$48 zfgUDXC-08v8it^EX>b9#=vJ9^xmNqMps!AL(r1k;c5c!E5==5afb z@}wr`ZUyD(Px5Aprich;r-V&4_z9y+4@Kd&G3AA;@%i^&kGpGxd*$tlclHJql=mTe zm~;T1Hf*k+2Yi$Bp`6>Tl*g?&cZWYoQ`Am4`WPak9Vkz_a&B*@JU&34!}LaXvndb% z?pyqsgXMV2vuOq8y^$U!>Vh@eOhuKO z%z6H*RbkO-ZdXwroWZ%PJdw>g{fA5cL}c^?%9CkGk><8D<-s$YyHS+K4+%#TNCfi= z<)*tN(&P3g&cEZMyCWwRGo#CE8lg-#R#4uH<#qatQU39!;s^ALbb0TjJew?0dECyW zyzu3{@bO=d?mnkHK3P^n+)f9x&t$e5vL1+Ca~o0~PvP8MM|pIn1cM%xDDQaA^SA8s zQ}wugm-BikuXMna(Os3NSb6iG^NNW)r-JgHD6iAyjm9FXHaeqSD351zZp$ez{25kZ z&U$qBD&;}#m2z&7wvx!`CeHKsbPA^u&28N&Y&8@vLlN%UQ69IF@}f5;f*C}4w3c)G z4CUD{oNdond3Rq5_jd20k{PsgEcs})?^HJDGr%|45kVWTldjsXk>Jy3u z@VHAT5B5QMrJW^$SPu2_d(%k+?U%j?#c?TIe$P86Ye4xGttWvlQ7S)IcKxvvb@Lbag?VyT(@1RF2uSkDUUCb3+L$a ziD2%dJbD22lBS@-?MsvgV>ox;Qy$F_j#i}z=71S2GtpGe?YWePqd9j&gzNIg-6WCd zuvxNuXVJq%8|5(QA&Nks&UnJ1=%3Vu&)L2IMxP6pz z^F8jt>CxR%%9GcHqeUt*^E>6?8+fYeFSU~G(a*BXnBV1&k;h#mT$eYRh}9sSJxj_v zk{%|mF1r`KOEHN>l!uK_uMhMjexy8@&$&Bj7MpXl4g5VddhR^RgOqc7E9KeuoV#h1 z$8QKnYgS}t4d=5sx4X_}Qw^4K?oJi1%NyS(s{tKFOUm1uA11&mlAfuU#N(8w4LG;U zC^z`&6mN9*2j$sbD1dZRMKBHKuoQ(gIk%Sc?VP*2DG#Q|I|W+8BADkXPfzFEeoc8W z9;cF<)k=1U%q>n;mp6P@Vn@T%lJcG}uhUI?t9!0r#vi|PXr!!FH)XN!Y_qM zlUW4wE#={_GP=iYo%w94K?}~^S(GP7;|_YD*IIwdv%@*JlPC{bVE5|L-8$i3d3VBE z8&JXR{A$m$Ih*5AUTI;AjJDwXFgc9JZFkDEi{*^varZFgX&o6I&216PTa-upa&CX6 zJgblLO6y!1-5v1)%S<*1+fh37BAAYphf8FCdEDMXc`}J}w@|n)ulWmQ`a#a+{vD(5 z=wS>V@I&idOk)2R*_`7ZsF!rw6>iU=JVc5-?rx$yJ5MHorn(5`DazwYD6jP3MKB*y zo;By(?Yw|ZHCv5fHmG;UTocaM%XJEm+p8##Lb(IsaW_u5SKduBI{Mz0l=p3Vn8J^# z<(L^Zs2;SvxsdelOeqUbx$-6fQpgK_EYO?BlbHtsa$dMxSdCN z_@dkb^0@ng^7KoI9gT~TnHn##sfOL;YtEmPD{dZlw+Pqe4e(14=(k%^-l_C3 zNhAEeJ^t)l+ElHkJRQ!t-Q{IE=W25I-y7XErQ9GG^cqGmT`5nh;+FVWb;I3`p**h6 zxqFTBuo|Y?K#iXJh4MI+hdVrOgGDSe(NTPKmlLkb8?V7*FP}*;{>gb5Jxp>m4zs8J zliK;5ua(CyJZ`_DJibJt^0=${3Y&Abw*-S8$0+aVl;?kwtN8p&q6%R9a9)pd_ax=f z!Ll^bs2Rb$PkC^TJlx@N`#0s$7S3I>w3r!PUV}2Bzi>%;yUFYH7bDY94ucNLn8aAh zlk@N}&hBb8*f%Ior{Z}f&D|EtgN@h$>(%JFLtka9A%9D}P+pJQiztr=bM9iwlhyK< z&u9>h%sfkZ{)#~HF~GC+TKkl8gEl%IceP(*%8)Ik?n}i&6q?# z%0uigkK2iqr?dI!ZUyDhe%N12Rf=*uz0S%TcEXcfn%l;dr~mvkk>;)w=asPVo9STg zr#zd7U^KTcbKV^LM02-QxZb_l8d>;gyIfMKAV06u`qde&?3*Y0e zT(~Z8{0p{KnfyML|H=7PdKfbuQ8m|-*hG0+hjUwZDV=jSoXhp-t{vwyWOTIlMtKKO zp4G(}D^Q=r>@$?dzwy!CTFSF35X1@}M#w-7TQp{En#_-7{+=<>}*`+x^~UQ;miqGkSD)p>SQ^Xm>nT zwzz^mMz_(!B#q?S4EmZQqcb`G8P8fRR@as6dddqO1M=6zJnpK$$L1UygU8W2sL^vR zDUZ8xZhKIkZo!2;J-T~@a#IBv{Z)flXa3;vpPK_HMe{8?bJtr=&YAP9HY8Yd7Z+l&r&ewMA-m9!FB5Av(XTPY5 zF=qL{+#c=Ax|Q`Q>)oY{+yCRg?JrHOv}VcbvblqPi4XquutEA|-yWp@|NqZ_+uVpA TpKkql@DCfSf6;$r{c8UMBTv9I diff --git a/interface/resources/avatar/animations/jump_land.fbx b/interface/resources/avatar/animations/jump_land.fbx index c0034bd091c6c28848b5942acee3c06387e21b5c..f057c80085c0049aa1d3734eb2fd836ee9d6b952 100644 GIT binary patch literal 923232 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