From 8bf9b70915002ca49b8ad100164ddd108c70093f Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 8 Mar 2017 14:08:33 -0800 Subject: [PATCH 01/14] Revert "don't blend animations for otherAvatars" This reverts commit faa272c67c103e36b5324ecc8eb14bb18e773745. --- interface/src/avatar/CauterizedModel.cpp | 6 ++ interface/src/avatar/CauterizedModel.h | 1 + interface/src/avatar/SkeletonModel.cpp | 4 +- libraries/animation/src/Rig.cpp | 71 ++++++++++-------------- 4 files changed, 39 insertions(+), 43 deletions(-) diff --git a/interface/src/avatar/CauterizedModel.cpp b/interface/src/avatar/CauterizedModel.cpp index 0c3d863649..843779dd3b 100644 --- a/interface/src/avatar/CauterizedModel.cpp +++ b/interface/src/avatar/CauterizedModel.cpp @@ -95,6 +95,12 @@ void CauterizedModel::createCollisionRenderItemSet() { Model::createCollisionRenderItemSet(); } +// Called within Model::simulate call, below. +void CauterizedModel::updateRig(float deltaTime, glm::mat4 parentTransform) { + Model::updateRig(deltaTime, parentTransform); + _needsUpdateClusterMatrices = true; +} + void CauterizedModel::updateClusterMatrices() { PerformanceTimer perfTimer("CauterizedModel::updateClusterMatrices"); diff --git a/interface/src/avatar/CauterizedModel.h b/interface/src/avatar/CauterizedModel.h index ba12aee32b..01e0b13650 100644 --- a/interface/src/avatar/CauterizedModel.h +++ b/interface/src/avatar/CauterizedModel.h @@ -37,6 +37,7 @@ public: void createVisibleRenderItemSet() override; void createCollisionRenderItemSet() override; + virtual void updateRig(float deltaTime, glm::mat4 parentTransform) override; virtual void updateClusterMatrices() override; void updateRenderItems() override; diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 88590a6f69..4b77323bba 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -166,7 +166,7 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { _rig->computeMotionAnimationState(deltaTime, position, velocity, orientation, ccState); // evaluate AnimGraph animation and update jointStates. - Model::updateRig(deltaTime, parentTransform); + CauterizedModel::updateRig(deltaTime, parentTransform); Rig::EyeParameters eyeParams; eyeParams.worldHeadOrientation = headParams.worldHeadOrientation; @@ -179,7 +179,7 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { _rig->updateFromEyeParameters(eyeParams); } else { - Model::updateRig(deltaTime, parentTransform); + CauterizedModel::updateRig(deltaTime, parentTransform); // This is a little more work than we really want. // diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 84e34adec7..c47da7c0b0 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1307,50 +1307,39 @@ void Rig::copyJointsIntoJointData(QVector& jointDataVec) const { void Rig::copyJointsFromJointData(const QVector& jointDataVec) { PerformanceTimer perfTimer("copyJoints"); PROFILE_RANGE(simulation_animation_detail, "copyJoints"); - if (!_animSkeleton) { - return; - } - if (jointDataVec.size() != (int)_internalPoseSet._relativePoses.size()) { - // animations haven't fully loaded yet. - _internalPoseSet._relativePoses = _animSkeleton->getRelativeDefaultPoses(); - } + if (_animSkeleton && jointDataVec.size() == (int)_internalPoseSet._relativePoses.size()) { + // make a vector of rotations in absolute-geometry-frame + const AnimPoseVec& absoluteDefaultPoses = _animSkeleton->getAbsoluteDefaultPoses(); + std::vector rotations; + rotations.reserve(absoluteDefaultPoses.size()); + const glm::quat rigToGeometryRot(glmExtractRotation(_rigToGeometryTransform)); + for (int i = 0; i < jointDataVec.size(); i++) { + const JointData& data = jointDataVec.at(i); + if (data.rotationSet) { + // JointData rotations are in absolute rig-frame so we rotate them to absolute geometry-frame + rotations.push_back(rigToGeometryRot * data.rotation); + } else { + rotations.push_back(absoluteDefaultPoses[i].rot()); + } + } - // make a vector of rotations in absolute-geometry-frame - const AnimPoseVec& absoluteDefaultPoses = _animSkeleton->getAbsoluteDefaultPoses(); - std::vector rotations; - rotations.reserve(absoluteDefaultPoses.size()); - const glm::quat rigToGeometryRot(glmExtractRotation(_rigToGeometryTransform)); - for (int i = 0; i < jointDataVec.size(); i++) { - const JointData& data = jointDataVec.at(i); - if (data.rotationSet) { - // JointData rotations are in absolute rig-frame so we rotate them to absolute geometry-frame - rotations.push_back(rigToGeometryRot * data.rotation); - } else { - rotations.push_back(absoluteDefaultPoses[i].rot()); + // convert rotations from absolute to parent relative. + _animSkeleton->convertAbsoluteRotationsToRelative(rotations); + + // store new relative poses + const AnimPoseVec& relativeDefaultPoses = _animSkeleton->getRelativeDefaultPoses(); + for (int i = 0; i < jointDataVec.size(); i++) { + const JointData& data = jointDataVec.at(i); + _internalPoseSet._relativePoses[i].scale() = Vectors::ONE; + _internalPoseSet._relativePoses[i].rot() = rotations[i]; + if (data.translationSet) { + // JointData translations are in scaled relative-frame so we scale back to regular relative-frame + _internalPoseSet._relativePoses[i].trans() = _invGeometryOffset.scale() * data.translation; + } else { + _internalPoseSet._relativePoses[i].trans() = relativeDefaultPoses[i].trans(); + } } } - - // convert rotations from absolute to parent relative. - _animSkeleton->convertAbsoluteRotationsToRelative(rotations); - - // store new relative poses - const AnimPoseVec& relativeDefaultPoses = _animSkeleton->getRelativeDefaultPoses(); - for (int i = 0; i < jointDataVec.size(); i++) { - const JointData& data = jointDataVec.at(i); - _internalPoseSet._relativePoses[i].scale() = Vectors::ONE; - _internalPoseSet._relativePoses[i].rot() = rotations[i]; - if (data.translationSet) { - // JointData translations are in scaled relative-frame so we scale back to regular relative-frame - _internalPoseSet._relativePoses[i].trans() = _invGeometryOffset.scale() * data.translation; - } else { - _internalPoseSet._relativePoses[i].trans() = relativeDefaultPoses[i].trans(); - } - } - - // build absolute poses and copy to externalPoseSet - buildAbsoluteRigPoses(_internalPoseSet._relativePoses, _internalPoseSet._absolutePoses); - QWriteLocker writeLock(&_externalPoseSetLock); - _externalPoseSet = _internalPoseSet; } void Rig::computeAvatarBoundingCapsule( From 9a9f07df7111322e21371ffa4938b4691b235c24 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 8 Mar 2017 14:08:48 -0800 Subject: [PATCH 02/14] Revert "expand avatar update time budget" This reverts commit 4bbbcb61be14c8233987941ad1fc89d4a6934e32. --- interface/src/avatar/AvatarManager.cpp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 7417f73102..6b426bcde8 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -157,6 +157,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { lock.unlock(); PerformanceTimer perfTimer("otherAvatars"); + uint64_t startTime = usecTimestampNow(); auto avatarMap = getHashCopy(); QList avatarList = avatarMap.values(); @@ -193,9 +194,10 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { }); render::PendingChanges pendingChanges; - uint64_t startTime = usecTimestampNow(); - const uint64_t UPDATE_BUDGET = 2000; // usec - uint64_t updateExpiry = startTime + UPDATE_BUDGET; + const uint64_t RENDER_UPDATE_BUDGET = 1500; // usec + const uint64_t MAX_UPDATE_BUDGET = 2000; // usec + uint64_t renderExpiry = startTime + RENDER_UPDATE_BUDGET; + uint64_t maxExpiry = startTime + MAX_UPDATE_BUDGET; int numAvatarsUpdated = 0; int numAVatarsNotUpdated = 0; @@ -221,7 +223,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { const float OUT_OF_VIEW_THRESHOLD = 0.5f * AvatarData::OUT_OF_VIEW_PENALTY; uint64_t now = usecTimestampNow(); - if (now < updateExpiry) { + if (now < renderExpiry) { // we're within budget bool inView = sortData.priority > OUT_OF_VIEW_THRESHOLD; if (inView && avatar->hasNewJointData()) { @@ -230,13 +232,21 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { avatar->simulate(deltaTime, inView); avatar->updateRenderItem(pendingChanges); avatar->setLastRenderUpdateTime(startTime); + } else if (now < maxExpiry) { + // we've spent most of our time budget, but we still simulate() the avatar as it if were out of view + // --> some avatars may freeze until their priority trickles up + bool inView = sortData.priority > OUT_OF_VIEW_THRESHOLD; + if (inView && avatar->hasNewJointData()) { + numAVatarsNotUpdated++; + } + avatar->simulate(deltaTime, false); } else { - // we've spent our full time budget --> bail on the rest of the avatar updates + // we've spent ALL of our time budget --> bail on the rest of the avatar updates // --> more avatars may freeze until their priority trickles up // --> some scale or fade animations may glitch // --> some avatar velocity measurements may be a little off - // no time simulate, but we take the time to count how many were tragically missed + // HACK: no time simulate, but we will take the time to count how many were tragically missed bool inView = sortData.priority > OUT_OF_VIEW_THRESHOLD; if (!inView) { break; From 188287e345ff43dcc11c79bf20376fba775d5699 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 8 Mar 2017 14:08:52 -0800 Subject: [PATCH 03/14] Revert "minor cleanup" This reverts commit 14e7392a89e3291891bb00bdb44349995f0aeac1. --- interface/src/avatar/Avatar.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 6e1f44f5ac..f5fe82ef4b 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -351,6 +351,7 @@ void Avatar::simulate(float deltaTime, bool inView) { _jointDataSimulationRate.increment(); _skeletonModel->simulate(deltaTime, true); + _skeletonModelSimulationRate.increment(); locationChanged(); // joints changed, so if there are any children, update them. _hasNewJointData = false; @@ -366,8 +367,8 @@ void Avatar::simulate(float deltaTime, bool inView) { } else { // a non-full update is still required so that the position, rotation, scale and bounds of the skeletonModel are updated. _skeletonModel->simulate(deltaTime, false); + _skeletonModelSimulationRate.increment(); } - _skeletonModelSimulationRate.increment(); } // update animation for display name fade in/out From a68674adccedab1004e1dbc0ec9e811eb5f2d4b4 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 8 Mar 2017 14:08:54 -0800 Subject: [PATCH 04/14] Revert "remove unnecessary context brackets" This reverts commit 0657ca1e5e4096daa30e28791e10f5aa05ca48c8. --- libraries/avatars/src/AvatarData.cpp | 78 ++++++++++++++-------------- 1 file changed, 40 insertions(+), 38 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 8025c680ca..6e4553ff8a 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -2332,48 +2332,50 @@ void AvatarData::sortAvatars( std::function getBoundingRadius, std::function shouldIgnore) { - PROFILE_RANGE(simulation, "sort"); - uint64_t now = usecTimestampNow(); + { + PROFILE_RANGE(simulation, "sort"); + uint64_t now = usecTimestampNow(); - glm::vec3 frustumCenter = cameraView.getPosition(); - const glm::vec3& forward = cameraView.getDirection(); - for (int32_t i = 0; i < avatarList.size(); ++i) { - const auto& avatar = avatarList.at(i); + glm::vec3 frustumCenter = cameraView.getPosition(); + const glm::vec3& forward = cameraView.getDirection(); + for (int32_t i = 0; i < avatarList.size(); ++i) { + const auto& avatar = avatarList.at(i); - if (shouldIgnore(avatar)) { - continue; - } - - // priority = weighted linear combination of: - // (a) apparentSize - // (b) proximity to center of view - // (c) time since last update - glm::vec3 avatarPosition = avatar->getPosition(); - glm::vec3 offset = avatarPosition - frustumCenter; - float distance = glm::length(offset) + 0.001f; // add 1mm to avoid divide by zero - - // FIXME - AvatarData has something equivolent to this - float radius = getBoundingRadius(avatar); - - float apparentSize = 2.0f * radius / distance; - float cosineAngle = glm::dot(offset, forward) / distance; - float age = (float)(now - getLastUpdated(avatar)) / (float)(USECS_PER_SECOND); - - // NOTE: we are adding values of different units to get a single measure of "priority". - // Thus we multiply each component by a conversion "weight" that scales its units relative to the others. - // These weights are pure magic tuning and should be hard coded in the relation below, - // but are currently exposed for anyone who would like to explore fine tuning: - float priority = _avatarSortCoefficientSize * apparentSize - + _avatarSortCoefficientCenter * cosineAngle - + _avatarSortCoefficientAge * age; - - // decrement priority of avatars outside keyhole - if (distance > cameraView.getCenterRadius()) { - if (!cameraView.sphereIntersectsFrustum(avatarPosition, radius)) { - priority += OUT_OF_VIEW_PENALTY; + if (shouldIgnore(avatar)) { + continue; } + + // priority = weighted linear combination of: + // (a) apparentSize + // (b) proximity to center of view + // (c) time since last update + glm::vec3 avatarPosition = avatar->getPosition(); + glm::vec3 offset = avatarPosition - frustumCenter; + float distance = glm::length(offset) + 0.001f; // add 1mm to avoid divide by zero + + // FIXME - AvatarData has something equivolent to this + float radius = getBoundingRadius(avatar); + + float apparentSize = 2.0f * radius / distance; + float cosineAngle = glm::dot(offset, forward) / distance; + float age = (float)(now - getLastUpdated(avatar)) / (float)(USECS_PER_SECOND); + + // NOTE: we are adding values of different units to get a single measure of "priority". + // Thus we multiply each component by a conversion "weight" that scales its units relative to the others. + // These weights are pure magic tuning and should be hard coded in the relation below, + // but are currently exposed for anyone who would like to explore fine tuning: + float priority = _avatarSortCoefficientSize * apparentSize + + _avatarSortCoefficientCenter * cosineAngle + + _avatarSortCoefficientAge * age; + + // decrement priority of avatars outside keyhole + if (distance > cameraView.getCenterRadius()) { + if (!cameraView.sphereIntersectsFrustum(avatarPosition, radius)) { + priority += OUT_OF_VIEW_PENALTY; + } + } + sortedAvatarsOut.push(AvatarPriority(avatar, priority)); } - sortedAvatarsOut.push(AvatarPriority(avatar, priority)); } } From 50288bd4ba3591aa0cffadfc994606143f349ea5 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 8 Mar 2017 14:08:56 -0800 Subject: [PATCH 05/14] Revert "remove unused variable" This reverts commit 92a32b46512094c1acd82fcd6c65c1d6ee49713b. --- assignment-client/src/avatars/AvatarMixerSlave.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index 49b4b1ced4..584d3d0e6a 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -168,6 +168,7 @@ void AvatarMixerSlave::broadcastAvatarData(const SharedNodePointer& node) { QList avatarList; std::unordered_map avatarDataToNodes; + int listItem = 0; std::for_each(_begin, _end, [&](const SharedNodePointer& otherNode) { const AvatarMixerClientData* otherNodeData = reinterpret_cast(otherNode->getLinkedData()); @@ -175,6 +176,7 @@ void AvatarMixerSlave::broadcastAvatarData(const SharedNodePointer& node) { // but not have yet sent data that's linked to the node. Check for that case and don't // consider those nodes. if (otherNodeData) { + listItem++; AvatarSharedPointer otherAvatar = otherNodeData->getAvatarSharedPointer(); avatarList << otherAvatar; avatarDataToNodes[otherAvatar] = otherNode; From 97c376a09c99f567b0fa90abd490eb542cd93c42 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 8 Mar 2017 14:08:58 -0800 Subject: [PATCH 06/14] Revert "avoid unnecessary copy of priority_queue" This reverts commit e54812430e871190fca541e2d3d744aee5e997d3. --- .../src/avatars/AvatarMixerSlave.cpp | 4 +-- interface/src/avatar/AvatarManager.cpp | 4 +-- libraries/avatars/src/AvatarData.cpp | 28 ++++++++++--------- libraries/avatars/src/AvatarData.h | 3 +- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index 584d3d0e6a..dd25aa4c4b 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -185,8 +185,8 @@ void AvatarMixerSlave::broadcastAvatarData(const SharedNodePointer& node) { AvatarSharedPointer thisAvatar = nodeData->getAvatarSharedPointer(); ViewFrustum cameraView = nodeData->getViewFrustom(); - std::priority_queue sortedAvatars; - AvatarData::sortAvatars(avatarList, cameraView, sortedAvatars, + std::priority_queue sortedAvatars = AvatarData::sortAvatars( + avatarList, cameraView, [&](AvatarSharedPointer avatar)->uint64_t{ auto avatarNode = avatarDataToNodes[avatar]; diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 6b426bcde8..d806c042b9 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -164,8 +164,8 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { ViewFrustum cameraView; qApp->copyDisplayViewFrustum(cameraView); - std::priority_queue sortedAvatars; - AvatarData::sortAvatars(avatarList, cameraView, sortedAvatars, + std::priority_queue sortedAvatars = AvatarData::sortAvatars( + avatarList, cameraView, [](AvatarSharedPointer avatar)->uint64_t{ return std::static_pointer_cast(avatar)->getLastRenderUpdateTime(); diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 6e4553ff8a..e7ec201aa1 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -2324,20 +2324,20 @@ float AvatarData::_avatarSortCoefficientSize { 0.5f }; float AvatarData::_avatarSortCoefficientCenter { 0.25 }; float AvatarData::_avatarSortCoefficientAge { 1.0f }; -void AvatarData::sortAvatars( - QList avatarList, - const ViewFrustum& cameraView, - std::priority_queue& sortedAvatarsOut, - std::function getLastUpdated, - std::function getBoundingRadius, - std::function shouldIgnore) { +std::priority_queue AvatarData::sortAvatars( + QList avatarList, + const ViewFrustum& cameraView, + std::function getLastUpdated, + std::function getBoundingRadius, + std::function shouldIgnore) { + uint64_t startTime = usecTimestampNow(); + + glm::vec3 frustumCenter = cameraView.getPosition(); + + std::priority_queue sortedAvatars; { PROFILE_RANGE(simulation, "sort"); - uint64_t now = usecTimestampNow(); - - glm::vec3 frustumCenter = cameraView.getPosition(); - const glm::vec3& forward = cameraView.getDirection(); for (int32_t i = 0; i < avatarList.size(); ++i) { const auto& avatar = avatarList.at(i); @@ -2356,9 +2356,10 @@ void AvatarData::sortAvatars( // FIXME - AvatarData has something equivolent to this float radius = getBoundingRadius(avatar); + const glm::vec3& forward = cameraView.getDirection(); float apparentSize = 2.0f * radius / distance; float cosineAngle = glm::dot(offset, forward) / distance; - float age = (float)(now - getLastUpdated(avatar)) / (float)(USECS_PER_SECOND); + float age = (float)(startTime - getLastUpdated(avatar)) / (float)(USECS_PER_SECOND); // NOTE: we are adding values of different units to get a single measure of "priority". // Thus we multiply each component by a conversion "weight" that scales its units relative to the others. @@ -2374,9 +2375,10 @@ void AvatarData::sortAvatars( priority += OUT_OF_VIEW_PENALTY; } } - sortedAvatarsOut.push(AvatarPriority(avatar, priority)); + sortedAvatars.push(AvatarPriority(avatar, priority)); } } + return sortedAvatars; } QScriptValue AvatarEntityMapToScriptValue(QScriptEngine* engine, const AvatarEntityMap& value) { diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index c2240f400f..12209d9c31 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -597,10 +597,9 @@ public: static const float OUT_OF_VIEW_PENALTY; - static void sortAvatars( + static std::priority_queue sortAvatars( QList avatarList, const ViewFrustum& cameraView, - std::priority_queue& sortedAvatarsOut, std::function getLastUpdated, std::function getBoundingRadius, std::function shouldIgnore); From a0befa7f958543445ffbc9d4a7975e92752cb127 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 8 Mar 2017 14:28:44 -0800 Subject: [PATCH 07/14] Trivial PR to trigger build --- interface/resources/qml/controls/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/resources/qml/controls/README.md b/interface/resources/qml/controls/README.md index 7f05f32a63..1245e42e97 100644 --- a/interface/resources/qml/controls/README.md +++ b/interface/resources/qml/controls/README.md @@ -1,2 +1,3 @@ These are our own custom controls with the same names as existing controls, but customized for readability / usability in VR. + From 1bba59a45903f4c94378bef89990a5bc0e857ad6 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 13 Mar 2017 14:38:02 -0700 Subject: [PATCH 08/14] Revert "Revert "avoid unnecessary copy of priority_queue"" This reverts commit 97c376a09c99f567b0fa90abd490eb542cd93c42. --- .../src/avatars/AvatarMixerSlave.cpp | 4 +-- interface/src/avatar/AvatarManager.cpp | 4 +-- libraries/avatars/src/AvatarData.cpp | 28 +++++++++---------- libraries/avatars/src/AvatarData.h | 3 +- 4 files changed, 19 insertions(+), 20 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index dd25aa4c4b..584d3d0e6a 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -185,8 +185,8 @@ void AvatarMixerSlave::broadcastAvatarData(const SharedNodePointer& node) { AvatarSharedPointer thisAvatar = nodeData->getAvatarSharedPointer(); ViewFrustum cameraView = nodeData->getViewFrustom(); - std::priority_queue sortedAvatars = AvatarData::sortAvatars( - avatarList, cameraView, + std::priority_queue sortedAvatars; + AvatarData::sortAvatars(avatarList, cameraView, sortedAvatars, [&](AvatarSharedPointer avatar)->uint64_t{ auto avatarNode = avatarDataToNodes[avatar]; diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index d806c042b9..6b426bcde8 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -164,8 +164,8 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { ViewFrustum cameraView; qApp->copyDisplayViewFrustum(cameraView); - std::priority_queue sortedAvatars = AvatarData::sortAvatars( - avatarList, cameraView, + std::priority_queue sortedAvatars; + AvatarData::sortAvatars(avatarList, cameraView, sortedAvatars, [](AvatarSharedPointer avatar)->uint64_t{ return std::static_pointer_cast(avatar)->getLastRenderUpdateTime(); diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index e7ec201aa1..6e4553ff8a 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -2324,20 +2324,20 @@ float AvatarData::_avatarSortCoefficientSize { 0.5f }; float AvatarData::_avatarSortCoefficientCenter { 0.25 }; float AvatarData::_avatarSortCoefficientAge { 1.0f }; -std::priority_queue AvatarData::sortAvatars( - QList avatarList, - const ViewFrustum& cameraView, - std::function getLastUpdated, - std::function getBoundingRadius, - std::function shouldIgnore) { +void AvatarData::sortAvatars( + QList avatarList, + const ViewFrustum& cameraView, + std::priority_queue& sortedAvatarsOut, + std::function getLastUpdated, + std::function getBoundingRadius, + std::function shouldIgnore) { - uint64_t startTime = usecTimestampNow(); - - glm::vec3 frustumCenter = cameraView.getPosition(); - - std::priority_queue sortedAvatars; { PROFILE_RANGE(simulation, "sort"); + uint64_t now = usecTimestampNow(); + + glm::vec3 frustumCenter = cameraView.getPosition(); + const glm::vec3& forward = cameraView.getDirection(); for (int32_t i = 0; i < avatarList.size(); ++i) { const auto& avatar = avatarList.at(i); @@ -2356,10 +2356,9 @@ std::priority_queue AvatarData::sortAvatars( // FIXME - AvatarData has something equivolent to this float radius = getBoundingRadius(avatar); - const glm::vec3& forward = cameraView.getDirection(); float apparentSize = 2.0f * radius / distance; float cosineAngle = glm::dot(offset, forward) / distance; - float age = (float)(startTime - getLastUpdated(avatar)) / (float)(USECS_PER_SECOND); + float age = (float)(now - getLastUpdated(avatar)) / (float)(USECS_PER_SECOND); // NOTE: we are adding values of different units to get a single measure of "priority". // Thus we multiply each component by a conversion "weight" that scales its units relative to the others. @@ -2375,10 +2374,9 @@ std::priority_queue AvatarData::sortAvatars( priority += OUT_OF_VIEW_PENALTY; } } - sortedAvatars.push(AvatarPriority(avatar, priority)); + sortedAvatarsOut.push(AvatarPriority(avatar, priority)); } } - return sortedAvatars; } QScriptValue AvatarEntityMapToScriptValue(QScriptEngine* engine, const AvatarEntityMap& value) { diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 12209d9c31..c2240f400f 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -597,9 +597,10 @@ public: static const float OUT_OF_VIEW_PENALTY; - static std::priority_queue sortAvatars( + static void sortAvatars( QList avatarList, const ViewFrustum& cameraView, + std::priority_queue& sortedAvatarsOut, std::function getLastUpdated, std::function getBoundingRadius, std::function shouldIgnore); From 4637fcefe9321d217c7d30c1c250faf00221186e Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 13 Mar 2017 14:38:04 -0700 Subject: [PATCH 09/14] Revert "Revert "remove unused variable"" This reverts commit 50288bd4ba3591aa0cffadfc994606143f349ea5. --- assignment-client/src/avatars/AvatarMixerSlave.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index 584d3d0e6a..49b4b1ced4 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -168,7 +168,6 @@ void AvatarMixerSlave::broadcastAvatarData(const SharedNodePointer& node) { QList avatarList; std::unordered_map avatarDataToNodes; - int listItem = 0; std::for_each(_begin, _end, [&](const SharedNodePointer& otherNode) { const AvatarMixerClientData* otherNodeData = reinterpret_cast(otherNode->getLinkedData()); @@ -176,7 +175,6 @@ void AvatarMixerSlave::broadcastAvatarData(const SharedNodePointer& node) { // but not have yet sent data that's linked to the node. Check for that case and don't // consider those nodes. if (otherNodeData) { - listItem++; AvatarSharedPointer otherAvatar = otherNodeData->getAvatarSharedPointer(); avatarList << otherAvatar; avatarDataToNodes[otherAvatar] = otherNode; From 71eb24386b058fd20394fff10f3b6544531a8de5 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 13 Mar 2017 14:38:06 -0700 Subject: [PATCH 10/14] Revert "Revert "remove unnecessary context brackets"" This reverts commit a68674adccedab1004e1dbc0ec9e811eb5f2d4b4. --- libraries/avatars/src/AvatarData.cpp | 80 ++++++++++++++-------------- 1 file changed, 39 insertions(+), 41 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 6e4553ff8a..8025c680ca 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -2332,50 +2332,48 @@ void AvatarData::sortAvatars( std::function getBoundingRadius, std::function shouldIgnore) { - { - PROFILE_RANGE(simulation, "sort"); - uint64_t now = usecTimestampNow(); + PROFILE_RANGE(simulation, "sort"); + uint64_t now = usecTimestampNow(); - glm::vec3 frustumCenter = cameraView.getPosition(); - const glm::vec3& forward = cameraView.getDirection(); - for (int32_t i = 0; i < avatarList.size(); ++i) { - const auto& avatar = avatarList.at(i); + glm::vec3 frustumCenter = cameraView.getPosition(); + const glm::vec3& forward = cameraView.getDirection(); + for (int32_t i = 0; i < avatarList.size(); ++i) { + const auto& avatar = avatarList.at(i); - if (shouldIgnore(avatar)) { - continue; - } - - // priority = weighted linear combination of: - // (a) apparentSize - // (b) proximity to center of view - // (c) time since last update - glm::vec3 avatarPosition = avatar->getPosition(); - glm::vec3 offset = avatarPosition - frustumCenter; - float distance = glm::length(offset) + 0.001f; // add 1mm to avoid divide by zero - - // FIXME - AvatarData has something equivolent to this - float radius = getBoundingRadius(avatar); - - float apparentSize = 2.0f * radius / distance; - float cosineAngle = glm::dot(offset, forward) / distance; - float age = (float)(now - getLastUpdated(avatar)) / (float)(USECS_PER_SECOND); - - // NOTE: we are adding values of different units to get a single measure of "priority". - // Thus we multiply each component by a conversion "weight" that scales its units relative to the others. - // These weights are pure magic tuning and should be hard coded in the relation below, - // but are currently exposed for anyone who would like to explore fine tuning: - float priority = _avatarSortCoefficientSize * apparentSize - + _avatarSortCoefficientCenter * cosineAngle - + _avatarSortCoefficientAge * age; - - // decrement priority of avatars outside keyhole - if (distance > cameraView.getCenterRadius()) { - if (!cameraView.sphereIntersectsFrustum(avatarPosition, radius)) { - priority += OUT_OF_VIEW_PENALTY; - } - } - sortedAvatarsOut.push(AvatarPriority(avatar, priority)); + if (shouldIgnore(avatar)) { + continue; } + + // priority = weighted linear combination of: + // (a) apparentSize + // (b) proximity to center of view + // (c) time since last update + glm::vec3 avatarPosition = avatar->getPosition(); + glm::vec3 offset = avatarPosition - frustumCenter; + float distance = glm::length(offset) + 0.001f; // add 1mm to avoid divide by zero + + // FIXME - AvatarData has something equivolent to this + float radius = getBoundingRadius(avatar); + + float apparentSize = 2.0f * radius / distance; + float cosineAngle = glm::dot(offset, forward) / distance; + float age = (float)(now - getLastUpdated(avatar)) / (float)(USECS_PER_SECOND); + + // NOTE: we are adding values of different units to get a single measure of "priority". + // Thus we multiply each component by a conversion "weight" that scales its units relative to the others. + // These weights are pure magic tuning and should be hard coded in the relation below, + // but are currently exposed for anyone who would like to explore fine tuning: + float priority = _avatarSortCoefficientSize * apparentSize + + _avatarSortCoefficientCenter * cosineAngle + + _avatarSortCoefficientAge * age; + + // decrement priority of avatars outside keyhole + if (distance > cameraView.getCenterRadius()) { + if (!cameraView.sphereIntersectsFrustum(avatarPosition, radius)) { + priority += OUT_OF_VIEW_PENALTY; + } + } + sortedAvatarsOut.push(AvatarPriority(avatar, priority)); } } From 031d144c0404d67264c59826b03ce8bbcf8fb72d Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 13 Mar 2017 14:38:08 -0700 Subject: [PATCH 11/14] Revert "Revert "minor cleanup"" This reverts commit 188287e345ff43dcc11c79bf20376fba775d5699. --- interface/src/avatar/Avatar.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index f5fe82ef4b..6e1f44f5ac 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -351,7 +351,6 @@ void Avatar::simulate(float deltaTime, bool inView) { _jointDataSimulationRate.increment(); _skeletonModel->simulate(deltaTime, true); - _skeletonModelSimulationRate.increment(); locationChanged(); // joints changed, so if there are any children, update them. _hasNewJointData = false; @@ -367,8 +366,8 @@ void Avatar::simulate(float deltaTime, bool inView) { } else { // a non-full update is still required so that the position, rotation, scale and bounds of the skeletonModel are updated. _skeletonModel->simulate(deltaTime, false); - _skeletonModelSimulationRate.increment(); } + _skeletonModelSimulationRate.increment(); } // update animation for display name fade in/out From 203325fd2a5761ef623ace5f67da477e0a380c48 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 13 Mar 2017 14:38:09 -0700 Subject: [PATCH 12/14] Revert "Revert "expand avatar update time budget"" This reverts commit 9a9f07df7111322e21371ffa4938b4691b235c24. --- interface/src/avatar/AvatarManager.cpp | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 6b426bcde8..7417f73102 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -157,7 +157,6 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { lock.unlock(); PerformanceTimer perfTimer("otherAvatars"); - uint64_t startTime = usecTimestampNow(); auto avatarMap = getHashCopy(); QList avatarList = avatarMap.values(); @@ -194,10 +193,9 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { }); render::PendingChanges pendingChanges; - const uint64_t RENDER_UPDATE_BUDGET = 1500; // usec - const uint64_t MAX_UPDATE_BUDGET = 2000; // usec - uint64_t renderExpiry = startTime + RENDER_UPDATE_BUDGET; - uint64_t maxExpiry = startTime + MAX_UPDATE_BUDGET; + uint64_t startTime = usecTimestampNow(); + const uint64_t UPDATE_BUDGET = 2000; // usec + uint64_t updateExpiry = startTime + UPDATE_BUDGET; int numAvatarsUpdated = 0; int numAVatarsNotUpdated = 0; @@ -223,7 +221,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { const float OUT_OF_VIEW_THRESHOLD = 0.5f * AvatarData::OUT_OF_VIEW_PENALTY; uint64_t now = usecTimestampNow(); - if (now < renderExpiry) { + if (now < updateExpiry) { // we're within budget bool inView = sortData.priority > OUT_OF_VIEW_THRESHOLD; if (inView && avatar->hasNewJointData()) { @@ -232,21 +230,13 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { avatar->simulate(deltaTime, inView); avatar->updateRenderItem(pendingChanges); avatar->setLastRenderUpdateTime(startTime); - } else if (now < maxExpiry) { - // we've spent most of our time budget, but we still simulate() the avatar as it if were out of view - // --> some avatars may freeze until their priority trickles up - bool inView = sortData.priority > OUT_OF_VIEW_THRESHOLD; - if (inView && avatar->hasNewJointData()) { - numAVatarsNotUpdated++; - } - avatar->simulate(deltaTime, false); } else { - // we've spent ALL of our time budget --> bail on the rest of the avatar updates + // we've spent our full time budget --> bail on the rest of the avatar updates // --> more avatars may freeze until their priority trickles up // --> some scale or fade animations may glitch // --> some avatar velocity measurements may be a little off - // HACK: no time simulate, but we will take the time to count how many were tragically missed + // no time simulate, but we take the time to count how many were tragically missed bool inView = sortData.priority > OUT_OF_VIEW_THRESHOLD; if (!inView) { break; From 0b237fa644265458868f8c93668bd95ca992347c Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 13 Mar 2017 15:17:35 -0700 Subject: [PATCH 13/14] Revert "Revert "don't blend animations for otherAvatars"" This reverts commit 8bf9b70915002ca49b8ad100164ddd108c70093f. --- interface/src/avatar/CauterizedModel.cpp | 6 -- interface/src/avatar/CauterizedModel.h | 1 - interface/src/avatar/SkeletonModel.cpp | 4 +- libraries/animation/src/Rig.cpp | 71 ++++++++++++++---------- 4 files changed, 43 insertions(+), 39 deletions(-) diff --git a/interface/src/avatar/CauterizedModel.cpp b/interface/src/avatar/CauterizedModel.cpp index 843779dd3b..0c3d863649 100644 --- a/interface/src/avatar/CauterizedModel.cpp +++ b/interface/src/avatar/CauterizedModel.cpp @@ -95,12 +95,6 @@ void CauterizedModel::createCollisionRenderItemSet() { Model::createCollisionRenderItemSet(); } -// Called within Model::simulate call, below. -void CauterizedModel::updateRig(float deltaTime, glm::mat4 parentTransform) { - Model::updateRig(deltaTime, parentTransform); - _needsUpdateClusterMatrices = true; -} - void CauterizedModel::updateClusterMatrices() { PerformanceTimer perfTimer("CauterizedModel::updateClusterMatrices"); diff --git a/interface/src/avatar/CauterizedModel.h b/interface/src/avatar/CauterizedModel.h index 01e0b13650..ba12aee32b 100644 --- a/interface/src/avatar/CauterizedModel.h +++ b/interface/src/avatar/CauterizedModel.h @@ -37,7 +37,6 @@ public: void createVisibleRenderItemSet() override; void createCollisionRenderItemSet() override; - virtual void updateRig(float deltaTime, glm::mat4 parentTransform) override; virtual void updateClusterMatrices() override; void updateRenderItems() override; diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 4b77323bba..88590a6f69 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -166,7 +166,7 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { _rig->computeMotionAnimationState(deltaTime, position, velocity, orientation, ccState); // evaluate AnimGraph animation and update jointStates. - CauterizedModel::updateRig(deltaTime, parentTransform); + Model::updateRig(deltaTime, parentTransform); Rig::EyeParameters eyeParams; eyeParams.worldHeadOrientation = headParams.worldHeadOrientation; @@ -179,7 +179,7 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { _rig->updateFromEyeParameters(eyeParams); } else { - CauterizedModel::updateRig(deltaTime, parentTransform); + Model::updateRig(deltaTime, parentTransform); // This is a little more work than we really want. // diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index c47da7c0b0..84e34adec7 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1307,39 +1307,50 @@ void Rig::copyJointsIntoJointData(QVector& jointDataVec) const { void Rig::copyJointsFromJointData(const QVector& jointDataVec) { PerformanceTimer perfTimer("copyJoints"); PROFILE_RANGE(simulation_animation_detail, "copyJoints"); - if (_animSkeleton && jointDataVec.size() == (int)_internalPoseSet._relativePoses.size()) { - // make a vector of rotations in absolute-geometry-frame - const AnimPoseVec& absoluteDefaultPoses = _animSkeleton->getAbsoluteDefaultPoses(); - std::vector rotations; - rotations.reserve(absoluteDefaultPoses.size()); - const glm::quat rigToGeometryRot(glmExtractRotation(_rigToGeometryTransform)); - for (int i = 0; i < jointDataVec.size(); i++) { - const JointData& data = jointDataVec.at(i); - if (data.rotationSet) { - // JointData rotations are in absolute rig-frame so we rotate them to absolute geometry-frame - rotations.push_back(rigToGeometryRot * data.rotation); - } else { - rotations.push_back(absoluteDefaultPoses[i].rot()); - } - } + if (!_animSkeleton) { + return; + } + if (jointDataVec.size() != (int)_internalPoseSet._relativePoses.size()) { + // animations haven't fully loaded yet. + _internalPoseSet._relativePoses = _animSkeleton->getRelativeDefaultPoses(); + } - // convert rotations from absolute to parent relative. - _animSkeleton->convertAbsoluteRotationsToRelative(rotations); - - // store new relative poses - const AnimPoseVec& relativeDefaultPoses = _animSkeleton->getRelativeDefaultPoses(); - for (int i = 0; i < jointDataVec.size(); i++) { - const JointData& data = jointDataVec.at(i); - _internalPoseSet._relativePoses[i].scale() = Vectors::ONE; - _internalPoseSet._relativePoses[i].rot() = rotations[i]; - if (data.translationSet) { - // JointData translations are in scaled relative-frame so we scale back to regular relative-frame - _internalPoseSet._relativePoses[i].trans() = _invGeometryOffset.scale() * data.translation; - } else { - _internalPoseSet._relativePoses[i].trans() = relativeDefaultPoses[i].trans(); - } + // make a vector of rotations in absolute-geometry-frame + const AnimPoseVec& absoluteDefaultPoses = _animSkeleton->getAbsoluteDefaultPoses(); + std::vector rotations; + rotations.reserve(absoluteDefaultPoses.size()); + const glm::quat rigToGeometryRot(glmExtractRotation(_rigToGeometryTransform)); + for (int i = 0; i < jointDataVec.size(); i++) { + const JointData& data = jointDataVec.at(i); + if (data.rotationSet) { + // JointData rotations are in absolute rig-frame so we rotate them to absolute geometry-frame + rotations.push_back(rigToGeometryRot * data.rotation); + } else { + rotations.push_back(absoluteDefaultPoses[i].rot()); } } + + // convert rotations from absolute to parent relative. + _animSkeleton->convertAbsoluteRotationsToRelative(rotations); + + // store new relative poses + const AnimPoseVec& relativeDefaultPoses = _animSkeleton->getRelativeDefaultPoses(); + for (int i = 0; i < jointDataVec.size(); i++) { + const JointData& data = jointDataVec.at(i); + _internalPoseSet._relativePoses[i].scale() = Vectors::ONE; + _internalPoseSet._relativePoses[i].rot() = rotations[i]; + if (data.translationSet) { + // JointData translations are in scaled relative-frame so we scale back to regular relative-frame + _internalPoseSet._relativePoses[i].trans() = _invGeometryOffset.scale() * data.translation; + } else { + _internalPoseSet._relativePoses[i].trans() = relativeDefaultPoses[i].trans(); + } + } + + // build absolute poses and copy to externalPoseSet + buildAbsoluteRigPoses(_internalPoseSet._relativePoses, _internalPoseSet._absolutePoses); + QWriteLocker writeLock(&_externalPoseSetLock); + _externalPoseSet = _internalPoseSet; } void Rig::computeAvatarBoundingCapsule( From a9658ce9fb7be82821759539fb1bc0820998f3c8 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 14 Mar 2017 17:15:23 -0700 Subject: [PATCH 14/14] Revert "Trivial PR to trigger build" This reverts commit a0befa7f958543445ffbc9d4a7975e92752cb127. --- interface/resources/qml/controls/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/resources/qml/controls/README.md b/interface/resources/qml/controls/README.md index 1245e42e97..7f05f32a63 100644 --- a/interface/resources/qml/controls/README.md +++ b/interface/resources/qml/controls/README.md @@ -1,3 +1,2 @@ These are our own custom controls with the same names as existing controls, but customized for readability / usability in VR. -