diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 64e82f63da..f8105eca16 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -306,13 +306,18 @@ bool Avatar::shouldDie() const { } void Avatar::simulate(float deltaTime, bool inView) { + _simulationRate.increment(); + PROFILE_RANGE(simulation, "simulate"); PerformanceTimer perfTimer("simulate"); { PROFILE_RANGE(simulation, "updateJoints"); if (inView && _hasNewJointData) { _skeletonModel->getRig()->copyJointsFromJointData(_jointData); + _jointDataSimulationRate.increment(); + _skeletonModel->simulate(deltaTime, true); + _skeletonModelSimulationRate.increment(); locationChanged(); // joints changed, so if there are any children, update them. _hasNewJointData = false; @@ -328,6 +333,7 @@ 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(); } } @@ -357,6 +363,18 @@ void Avatar::simulate(float deltaTime, bool inView) { } } +float Avatar::getSimulationRate(const QString& rateName) { + if (rateName == "") { + return _simulationRate.rate(); + } else if (rateName == "avatar") { + return _simulationRate.rate(); + } else if (rateName == "skeletonModel") { + return _skeletonModelSimulationRate.rate(); + } else if (rateName == "jointData") { + return _jointDataSimulationRate.rate(); + } +} + bool Avatar::isLookingAtMe(AvatarSharedPointer avatar) const { const float HEAD_SPHERE_RADIUS = 0.1f; glm::vec3 theirLookAt = dynamic_pointer_cast(avatar)->getHead()->getLookAtPosition(); diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 8f2b0817c1..e0d19fcbc1 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -182,6 +182,8 @@ public: void animateScaleChanges(float deltaTime); void setTargetScale(float targetScale) override; + Q_INVOKABLE float getSimulationRate(const QString& rateName = QString("")); + public slots: // FIXME - these should be migrated to use Pose data instead @@ -259,6 +261,12 @@ protected: void addToScene(AvatarSharedPointer self); void ensureInScene(AvatarSharedPointer self); + // Some rate tracking support + RateCounter<> _simulationRate; + RateCounter<> _skeletonModelSimulationRate; + RateCounter<> _jointDataSimulationRate; + + private: uint64_t _lastRenderUpdateTime { 0 }; int _leftPointerGeometryID { 0 }; diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index df3164e6fc..136d7cc016 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -137,6 +137,13 @@ float AvatarManager::getAvatarDataRate(const QUuid& sessionID, const QString& ra return avatar->getDataRate(rateName); } +float AvatarManager::getAvatarSimulationRate(const QUuid& sessionID, const QString& rateName) { + auto avatar = std::static_pointer_cast(getAvatarBySessionID(sessionID)); + return avatar ? avatar->getSimulationRate(rateName) : 0.0f; +} + + + class AvatarPriority { public: AvatarPriority(AvatarSharedPointer a, float p) : avatar(a), priority(p) {} diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index 787d6f2d83..c80fd14def 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -70,6 +70,8 @@ public: void handleCollisionEvents(const CollisionEvents& collisionEvents); Q_INVOKABLE float getAvatarDataRate(const QUuid& sessionID, const QString& rateName = QString("")); + Q_INVOKABLE float getAvatarSimulationRate(const QUuid& sessionID, const QString& rateName = QString("")); + Q_INVOKABLE RayToAvatarIntersectionResult findRayIntersection(const PickRay& ray, const QScriptValue& avatarIdsToInclude = QScriptValue(), const QScriptValue& avatarIdsToDiscard = QScriptValue()); diff --git a/scripts/developer/debugging/debugAvatarMixer.js b/scripts/developer/debugging/debugAvatarMixer.js index 6c0a935b70..1c11d308b8 100644 --- a/scripts/developer/debugging/debugAvatarMixer.js +++ b/scripts/developer/debugging/debugAvatarMixer.js @@ -60,7 +60,8 @@ function updateOverlays() { var overlayPosition = avatar.getJointPosition("Head"); overlayPosition.y += 1.05; - var text = " All: " + AvatarManager.getAvatarDataRate(avatarID).toFixed(2) + "\n" + var text = "--- Data from Mixer ----------------------\n" + +"All: " + AvatarManager.getAvatarDataRate(avatarID).toFixed(2) + "\n" +" GP: " + AvatarManager.getAvatarDataRate(avatarID,"globalPosition").toFixed(2) + "\n" +" LP: " + AvatarManager.getAvatarDataRate(avatarID,"localPosition").toFixed(2) + "\n" +" BB: " + AvatarManager.getAvatarDataRate(avatarID,"avatarBoundingBox").toFixed(2) + "\n" @@ -72,7 +73,11 @@ function updateOverlays() { +" AF: " + AvatarManager.getAvatarDataRate(avatarID,"additionalFlags").toFixed(2) + "\n" +" PI: " + AvatarManager.getAvatarDataRate(avatarID,"parentInfo").toFixed(2) + "\n" +" FT: " + AvatarManager.getAvatarDataRate(avatarID,"faceTracker").toFixed(2) + "\n" - +" JD: " + AvatarManager.getAvatarDataRate(avatarID,"jointData").toFixed(2); + +" JD: " + AvatarManager.getAvatarDataRate(avatarID,"jointData").toFixed(2) + +"--- Simulation ----------------------\n" + +"All: " + AvatarManager.getAvatarSimulationRate(avatarID,"avatar").toFixed(2) + "\n" + +" SM: " + AvatarManager.getAvatarSimulationRate(avatarID,"skeletonModel").toFixed(2) + "\n" + +" JS: " + AvatarManager.getAvatarSimulationRate(avatarID,"jointData").toFixed(2) + "\n" if (avatarID in debugOverlays) { // keep the overlay above the current position of this avatar