From eadb1758f9f3e8052f6ccfb9acf9c6d78e1c38b4 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 9 Jan 2017 17:07:47 -0800 Subject: [PATCH] adding some rate debugging --- libraries/avatars/src/AvatarData.cpp | 91 +++++++--- .../developer/debugging/debugAvatarMixer.js | 168 ++++++++++++++++++ 2 files changed, 231 insertions(+), 28 deletions(-) create mode 100644 scripts/developer/debugging/debugAvatarMixer.js diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index ec725609da..26a750f0c1 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -678,8 +678,6 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { AvatarDataPacket::HasFlags packetStateFlags; - _parseBufferRate.increment(); - const unsigned char* startPosition = reinterpret_cast(buffer.data()); const unsigned char* endPosition = startPosition + buffer.size(); const unsigned char* sourceBuffer = startPosition; @@ -709,6 +707,8 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { quint64 now = usecTimestampNow(); if (hasAvatarGlobalPosition) { + auto startSection = sourceBuffer; + 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]); @@ -719,10 +719,13 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { sourceBuffer += sizeof(AvatarDataPacket::AvatarGlobalPosition); //qDebug() << "hasAvatarGlobalPosition _globalPosition:" << _globalPosition; - _globalPositionRate.increment(); + int numBytesRead = sourceBuffer - startSection; + _globalPositionRate.increment(numBytesRead); } if (hasAvatarLocalPosition) { + auto startSection = sourceBuffer; + PACKET_READ_CHECK(AvatarLocalPosition, sizeof(AvatarDataPacket::AvatarLocalPosition)); auto data = reinterpret_cast(sourceBuffer); glm::vec3 position = glm::vec3(data->localPosition[0], data->localPosition[1], data->localPosition[2]); @@ -736,10 +739,13 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { sourceBuffer += sizeof(AvatarDataPacket::AvatarLocalPosition); //qDebug() << "hasAvatarLocalPosition position:" << position; - _localPositionRate.increment(); + int numBytesRead = sourceBuffer - startSection; + _localPositionRate.increment(numBytesRead); } if (hasAvatarDimensions) { + auto startSection = sourceBuffer; + PACKET_READ_CHECK(AvatarDimensions, sizeof(AvatarDataPacket::AvatarDimensions)); auto data = reinterpret_cast(sourceBuffer); auto newValue = glm::vec3(data->avatarDimensions[0], data->avatarDimensions[1], data->avatarDimensions[2]); @@ -751,10 +757,13 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { sourceBuffer += sizeof(AvatarDataPacket::AvatarDimensions); //qDebug() << "hasAvatarDimensions _globalBoundingBoxCorner:" << _globalBoundingBoxCorner; - _avatarDimensionRate.increment(); + int numBytesRead = sourceBuffer - startSection; + _avatarDimensionRate.increment(numBytesRead); } if (hasAvatarOrientation) { + auto startSection = sourceBuffer; + PACKET_READ_CHECK(AvatarOrientation, sizeof(AvatarDataPacket::AvatarOrientation)); auto data = reinterpret_cast(sourceBuffer); float pitch, yaw, roll; @@ -778,10 +787,13 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { sourceBuffer += sizeof(AvatarDataPacket::AvatarOrientation); //qDebug() << "hasAvatarOrientation newOrientation:" << newOrientation; - _avatarOrientationRate.increment(); + int numBytesRead = sourceBuffer - startSection; + _avatarOrientationRate.increment(numBytesRead); } if (hasAvatarScale) { + auto startSection = sourceBuffer; + PACKET_READ_CHECK(AvatarScale, sizeof(AvatarDataPacket::AvatarScale)); auto data = reinterpret_cast(sourceBuffer); float scale; @@ -796,10 +808,13 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { sourceBuffer += sizeof(AvatarDataPacket::AvatarScale); //qDebug() << "hasAvatarOrientation scale:" << scale; - _avatarScaleRate.increment(); + int numBytesRead = sourceBuffer - startSection; + _avatarScaleRate.increment(numBytesRead); } if (hasLookAtPosition) { + auto startSection = sourceBuffer; + PACKET_READ_CHECK(LookAtPosition, sizeof(AvatarDataPacket::LookAtPosition)); auto data = reinterpret_cast(sourceBuffer); glm::vec3 lookAt = glm::vec3(data->lookAtPosition[0], data->lookAtPosition[1], data->lookAtPosition[2]); @@ -813,10 +828,13 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { sourceBuffer += sizeof(AvatarDataPacket::LookAtPosition); //qDebug() << "hasLookAtPosition lookAt:" << lookAt; - _lookAtPositionRate.increment(); + int numBytesRead = sourceBuffer - startSection; + _lookAtPositionRate.increment(numBytesRead); } if (hasAudioLoudness) { + auto startSection = sourceBuffer; + PACKET_READ_CHECK(AudioLoudness, sizeof(AvatarDataPacket::AudioLoudness)); auto data = reinterpret_cast(sourceBuffer); float audioLoudness; @@ -832,10 +850,13 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { sourceBuffer += sizeof(AvatarDataPacket::AudioLoudness); //qDebug() << "hasAudioLoudness audioLoudness:" << audioLoudness; - _audioLoudnessRate.increment(); + int numBytesRead = sourceBuffer - startSection; + _audioLoudnessRate.increment(numBytesRead); } if (hasSensorToWorldMatrix) { + auto startSection = sourceBuffer; + PACKET_READ_CHECK(SensorToWorldMatrix, sizeof(AvatarDataPacket::SensorToWorldMatrix)); auto data = reinterpret_cast(sourceBuffer); glm::quat sensorToWorldQuat; @@ -851,11 +872,13 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { sourceBuffer += sizeof(AvatarDataPacket::SensorToWorldMatrix); //qDebug() << "hasSensorToWorldMatrix sensorToWorldMatrix:" << sensorToWorldMatrix; - _sensorToWorldRate.increment(); + int numBytesRead = sourceBuffer - startSection; + _sensorToWorldRate.increment(numBytesRead); } if (hasAdditionalFlags) { - //qDebug() << "hasAdditionalFlags..."; + auto startSection = sourceBuffer; + PACKET_READ_CHECK(AdditionalFlags, sizeof(AvatarDataPacket::AdditionalFlags)); auto data = reinterpret_cast(sourceBuffer); uint8_t bitItems = data->flags; @@ -892,12 +915,14 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { if (somethingChanged) { _additionalFlagsChanged = usecTimestampNow(); } - _additionalFlagsRate.increment(); + int numBytesRead = sourceBuffer - startSection; + _additionalFlagsRate.increment(numBytesRead); } // FIXME -- make sure to handle the existance of a parent vs a change in the parent... //bool hasReferential = oneAtBit(bitItems, HAS_REFERENTIAL); if (hasParentInfo) { + auto startSection = sourceBuffer; PACKET_READ_CHECK(ParentInfo, sizeof(AvatarDataPacket::ParentInfo)); auto parentInfo = reinterpret_cast(sourceBuffer); sourceBuffer += sizeof(AvatarDataPacket::ParentInfo); @@ -912,13 +937,16 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { _parentChanged = usecTimestampNow(); } - _parentInfoRate.increment(); + int numBytesRead = sourceBuffer - startSection; + _parentInfoRate.increment(numBytesRead); } else { // FIXME - this aint totally right, for switching to parent/no-parent _parentID = QUuid(); } if (hasFaceTrackerInfo) { + auto startSection = sourceBuffer; + PACKET_READ_CHECK(FaceTrackerInfo, sizeof(AvatarDataPacket::FaceTrackerInfo)); auto faceTrackerInfo = reinterpret_cast(sourceBuffer); sourceBuffer += sizeof(AvatarDataPacket::FaceTrackerInfo); @@ -936,10 +964,13 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { sourceBuffer += coefficientsSize; //qDebug() << "hasFaceTrackerInfo numCoefficients:" << numCoefficients; - _faceTrackerRate.increment(); + int numBytesRead = sourceBuffer - startSection; + _faceTrackerRate.increment(numBytesRead); } if (hasJointData) { + auto startSection = sourceBuffer; + PACKET_READ_CHECK(NumJoints, sizeof(uint8_t)); int numJoints = *sourceBuffer++; //qDebug() << __FUNCTION__ << "....hasJointData numJoints:" << numJoints; @@ -1029,41 +1060,45 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { //qDebug() << "hasJointData numValidJointRotations:" << numValidJointRotations << "numValidJointTranslations:" << numValidJointTranslations; - _jointDataRate.increment(); + int numBytesRead = sourceBuffer - startSection; + _jointDataRate.increment(numBytesRead); } int numBytesRead = sourceBuffer - startPosition; _averageBytesReceived.updateAverage(numBytesRead); + + _parseBufferRate.increment(numBytesRead); + return numBytesRead; } float AvatarData::getDataRate(const QString& rateName) { if (rateName == "") { - return _parseBufferRate.rate(); + return _parseBufferRate.rate() / BYTES_PER_KILOBIT; } else if (rateName == "globalPosition") { - return _globalPositionRate.rate(); + return _globalPositionRate.rate() / BYTES_PER_KILOBIT; } else if (rateName == "localPosition") { - return _localPositionRate.rate(); + return _localPositionRate.rate() / BYTES_PER_KILOBIT; } else if (rateName == "avatarDimensions") { - return _avatarDimensionRate.rate(); + return _avatarDimensionRate.rate() / BYTES_PER_KILOBIT; } else if (rateName == "avatarOrientation") { - return _avatarOrientationRate.rate(); + return _avatarOrientationRate.rate() / BYTES_PER_KILOBIT; } else if (rateName == "avatarScale") { - return _avatarScaleRate.rate(); + return _avatarScaleRate.rate() / BYTES_PER_KILOBIT; } else if (rateName == "lookAtPosition") { - return _lookAtPositionRate.rate(); + return _lookAtPositionRate.rate() / BYTES_PER_KILOBIT; } else if (rateName == "audioLoudness") { - return _audioLoudnessRate.rate(); + return _audioLoudnessRate.rate() / BYTES_PER_KILOBIT; } else if (rateName == "sensorToWorkMatrix") { - return _sensorToWorldRate.rate(); + return _sensorToWorldRate.rate() / BYTES_PER_KILOBIT; } else if (rateName == "additionalFlags") { - return _additionalFlagsRate.rate(); + return _additionalFlagsRate.rate() / BYTES_PER_KILOBIT; } else if (rateName == "parentInfo") { - return _parentInfoRate.rate(); + return _parentInfoRate.rate() / BYTES_PER_KILOBIT; } else if (rateName == "faceTracker") { - return _faceTrackerRate.rate(); + return _faceTrackerRate.rate() / BYTES_PER_KILOBIT; } else if (rateName == "jointData") { - return _jointDataRate.rate(); + return _jointDataRate.rate() / BYTES_PER_KILOBIT; } return 0.0f; } diff --git a/scripts/developer/debugging/debugAvatarMixer.js b/scripts/developer/debugging/debugAvatarMixer.js new file mode 100644 index 0000000000..2e7901b962 --- /dev/null +++ b/scripts/developer/debugging/debugAvatarMixer.js @@ -0,0 +1,168 @@ +"use strict"; + +// +// debugAvatarMixer.js +// scripts/developer/debugging +// +// Created by Brad Hefta-Gaub on 01/09/2017 +// Copyright 2017 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 Toolbars, Script, Users, Overlays, AvatarList, Controller, Camera, getControllerWorldLocation */ + + +(function() { // BEGIN LOCAL_SCOPE + +Script.include("/~/system/libraries/controllers.js"); + +// grab the toolbar +var toolbar = Toolbars.getToolbar("com.highfidelity.interface.toolbar.system"); + +var ASSETS_PATH = Script.resolvePath("assets"); +var TOOLS_PATH = Script.resolvePath("assets/images/tools/"); + +function buttonImageURL() { + return TOOLS_PATH + (Users.canKick ? 'kick.svg' : 'ignore.svg'); +} + +// setup the mod button and add it to the toolbar +var button = toolbar.addButton({ + objectName: 'debugAvatarMixer', + imageURL: buttonImageURL(), + visible: true, + buttonState: 1, + defaultState: 1, + hoverState: 3, + alpha: 0.9 +}); + +var isShowingOverlays = false; +var debugOverlays = {}; + +function removeOverlays() { + // enumerate the overlays and remove them + var overlayKeys = Object.keys(debugOverlays); + + for (var i = 0; i < overlayKeys.length; ++i) { + var avatarID = overlayKeys[i]; + for (var j = 0; j < debugOverlays[avatarID].length; ++j) { + Overlays.deleteOverlay(debugOverlays[avatarID][j]); + } + } + + debugOverlays = {}; +} + +// handle clicks on the toolbar button +function buttonClicked(){ + if (isShowingOverlays) { + removeOverlays(); + isShowingOverlays = false; + } else { + isShowingOverlays = true; + } + + button.writeProperty('buttonState', isShowingOverlays ? 0 : 1); + button.writeProperty('defaultState', isShowingOverlays ? 0 : 1); + button.writeProperty('hoverState', isShowingOverlays ? 2 : 3); +} + +button.clicked.connect(buttonClicked); + +function updateOverlays() { + if (isShowingOverlays) { + + var identifiers = AvatarList.getAvatarIdentifiers(); + + for (var i = 0; i < identifiers.length; ++i) { + var avatarID = identifiers[i]; + + if (avatarID === null) { + // this is our avatar, skip it + continue; + } + + // get the position for this avatar + var avatar = AvatarList.getAvatar(avatarID); + var avatarPosition = avatar && avatar.position; + + if (!avatarPosition) { + // we don't have a valid position for this avatar, skip it + continue; + } + + // setup a position for the overlay that is just above this avatar's head + var overlayPosition = avatar.getJointPosition("Head"); + overlayPosition.y += 1.05; + + var text = " All: " + AvatarManager.getAvatarDataRate(avatarID).toFixed(2) + "\n" + +" GP: " + AvatarManager.getAvatarDataRate(avatarID,"globalPosition").toFixed(2) + "\n" + +" LP: " + AvatarManager.getAvatarDataRate(avatarID,"localPosition").toFixed(2) + "\n" + +" AD: " + AvatarManager.getAvatarDataRate(avatarID,"avatarDimensions").toFixed(2) + "\n" + +" AO: " + AvatarManager.getAvatarDataRate(avatarID,"avatarOrientation").toFixed(2) + "\n" + +" AS: " + AvatarManager.getAvatarDataRate(avatarID,"avatarScale").toFixed(2) + "\n" + +" LA: " + AvatarManager.getAvatarDataRate(avatarID,"lookAtPosition").toFixed(2) + "\n" + +" AL: " + AvatarManager.getAvatarDataRate(avatarID,"audioLoudness").toFixed(2) + "\n" + +" SW: " + AvatarManager.getAvatarDataRate(avatarID,"sensorToWorkMatrix").toFixed(2) + "\n" + +" 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); + + if (avatarID in debugOverlays) { + // keep the overlay above the current position of this avatar + Overlays.editOverlay(debugOverlays[avatarID][0], { + position: overlayPosition, + text: text + }); + } else { + // add the overlay above this avatar + var newOverlay = Overlays.addOverlay("text3d", { + position: overlayPosition, + dimensions: { + x: 1, + y: 13 * 0.13 + }, + lineHeight: 0.1, + font:{size:0.1}, + text: text, + size: 1, + scale: 0.4, + color: { red: 255, green: 255, blue: 255}, + alpha: 1, + solid: true, + isFacingAvatar: true, + drawInFront: true + }); + + debugOverlays[avatarID]=[newOverlay]; + } + } + } +} + +Script.update.connect(updateOverlays); + +AvatarList.avatarRemovedEvent.connect(function(avatarID){ + if (isShowingOverlays) { + // we are currently showing overlays and an avatar just went away + + // first remove the rendered overlays + for (var j = 0; j < debugOverlays[avatarID].length; ++j) { + Overlays.deleteOverlay(debugOverlays[avatarID][j]); + } + + // delete the saved ID of the overlay from our mod overlays object + delete debugOverlays[avatarID]; + } +}); + +// cleanup the toolbar button and overlays when script is stopped +Script.scriptEnding.connect(function() { + toolbar.removeButton('debugAvatarMixer'); + removeOverlays(); +}); + +}()); // END LOCAL_SCOPE