12 #ifndef hifi_AvatarMixerClientData_h
13 #define hifi_AvatarMixerClientData_h
17 #include <unordered_map>
21 #include <QtCore/QJsonObject>
22 #include <QtCore/QSharedPointer>
23 #include <QtCore/QUrl>
25 #include "MixerAvatar.h"
26 #include <AssociatedTraitValues.h>
28 #include <NumericalConstants.h>
29 #include <udt/PacketHeaders.h>
30 #include <PortableHighResolutionClock.h>
31 #include <SimpleMovingAverage.h>
32 #include <UUIDHasher.h>
33 #include <shared/ConicalViewFrustum.h>
35 const QString OUTBOUND_AVATAR_DATA_STATS_KEY =
"outbound_av_data_kbps";
36 const QString OUTBOUND_AVATAR_TRAITS_STATS_KEY =
"outbound_av_traits_kbps";
37 const QString INBOUND_AVATAR_DATA_STATS_KEY =
"inbound_av_data_kbps";
39 struct SlaveSharedData;
41 class AvatarMixerClientData :
public NodeData {
44 AvatarMixerClientData(
const QUuid& nodeID, Node::LocalID nodeLocalID);
45 virtual ~AvatarMixerClientData() {}
46 using HRCTime = p_high_resolution_clock::time_point;
47 using PerNodeTraitVersions = std::unordered_map<Node::LocalID, AvatarTraits::TraitVersions>;
49 using NodeData::parseData;
50 int parseData(ReceivedMessage& message,
const SlaveSharedData& SlaveSharedData);
51 MixerAvatar& getAvatar() {
return *_avatar; }
52 const MixerAvatar& getAvatar()
const {
return *_avatar; }
53 const MixerAvatar* getConstAvatarData()
const {
return _avatar.get(); }
54 MixerAvatarSharedPointer getAvatarSharedPointer()
const {
return _avatar; }
56 uint16_t getLastBroadcastSequenceNumber(NLPacket::LocalID nodeID)
const;
57 void setLastBroadcastSequenceNumber(NLPacket::LocalID nodeID, uint16_t sequenceNumber)
58 { _lastBroadcastSequenceNumbers[nodeID] = sequenceNumber; }
59 Q_INVOKABLE
void removeLastBroadcastSequenceNumber(NLPacket::LocalID nodeID) { _lastBroadcastSequenceNumbers.erase(nodeID); }
60 bool isIgnoreRadiusEnabled()
const {
return _isIgnoreRadiusEnabled; }
61 void setIsIgnoreRadiusEnabled(
bool enabled) { _isIgnoreRadiusEnabled = enabled; }
63 uint64_t getLastBroadcastTime(NLPacket::LocalID nodeUUID)
const;
64 void setLastBroadcastTime(NLPacket::LocalID nodeUUID, uint64_t broadcastTime) { _lastBroadcastTimes[nodeUUID] = broadcastTime; }
65 Q_INVOKABLE
void removeLastBroadcastTime(NLPacket::LocalID nodeUUID) { _lastBroadcastTimes.erase(nodeUUID); }
67 Q_INVOKABLE
void cleanupKilledNode(
const QUuid& nodeUUID, Node::LocalID nodeLocalID);
69 uint16_t getLastReceivedSequenceNumber()
const {
return _lastReceivedSequenceNumber; }
71 uint64_t getIdentityChangeTimestamp()
const {
return _identityChangeTimestamp; }
72 void flagIdentityChange() { _identityChangeTimestamp = usecTimestampNow(); }
73 bool getAvatarSessionDisplayNameMustChange()
const {
return _avatarSessionDisplayNameMustChange; }
74 void setAvatarSessionDisplayNameMustChange(
bool set =
true) { _avatarSessionDisplayNameMustChange = set; }
76 void resetNumAvatarsSentLastFrame() { _numAvatarsSentLastFrame = 0; }
77 void incrementNumAvatarsSentLastFrame() { ++_numAvatarsSentLastFrame; }
78 int getNumAvatarsSentLastFrame()
const {
return _numAvatarsSentLastFrame; }
80 void recordNumOtherAvatarStarves(
int numAvatarsHeldBack) { _otherAvatarStarves.updateAverage((
float) numAvatarsHeldBack); }
81 float getAvgNumOtherAvatarStarvesPerSecond()
const {
return _otherAvatarStarves.getAverageSampleValuePerSecond(); }
83 void recordNumOtherAvatarSkips(
int numOtherAvatarSkips) { _otherAvatarSkips.updateAverage((
float) numOtherAvatarSkips); }
84 float getAvgNumOtherAvatarSkipsPerSecond()
const {
return _otherAvatarSkips.getAverageSampleValuePerSecond(); }
86 void incrementNumOutOfOrderSends() { ++_numOutOfOrderSends; }
88 int getNumFramesSinceFRDAdjustment()
const {
return _numFramesSinceAdjustment; }
89 void incrementNumFramesSinceFRDAdjustment() { ++_numFramesSinceAdjustment; }
90 void resetNumFramesSinceFRDAdjustment() { _numFramesSinceAdjustment = 0; }
92 void recordSentAvatarData(
int numDataBytes,
int numTraitsBytes = 0) {
93 _avgOtherAvatarDataRate.updateAverage(numDataBytes);
94 _avgOtherAvatarTraitsRate.updateAverage(numTraitsBytes);
97 float getOutboundAvatarDataKbps()
const
98 {
return _avgOtherAvatarDataRate.getAverageSampleValuePerSecond() / (float) BYTES_PER_KILOBIT; }
99 float getOutboundAvatarTraitsKbps()
const
100 {
return _avgOtherAvatarTraitsRate.getAverageSampleValuePerSecond() / BYTES_PER_KILOBIT; }
102 void loadJSONStats(QJsonObject& jsonObject)
const;
104 glm::vec3 getPosition()
const {
return _avatar ? _avatar->getClientGlobalPosition() : glm::vec3(0); }
105 bool isRadiusIgnoring(
const QUuid& other)
const;
106 void addToRadiusIgnoringSet(
const QUuid& other);
107 void removeFromRadiusIgnoringSet(
const QUuid& other);
108 void ignoreOther(SharedNodePointer
self, SharedNodePointer other);
109 void ignoreOther(
const Node*
self,
const Node* other);
111 void readViewFrustumPacket(
const QByteArray& message);
113 bool otherAvatarInView(
const AABox& otherAvatarBox);
115 void resetInViewStats() { _recentOtherAvatarsInView = _recentOtherAvatarsOutOfView = 0; }
116 void incrementAvatarInView() { _recentOtherAvatarsInView++; }
117 void incrementAvatarOutOfView() { _recentOtherAvatarsOutOfView++; }
118 const QString& getBaseDisplayName() {
return _baseDisplayName; }
119 void setBaseDisplayName(
const QString& baseDisplayName) { _baseDisplayName = baseDisplayName; }
120 bool getRequestsDomainListData() {
return _requestsDomainListData; }
121 void setRequestsDomainListData(
bool requesting) { _requestsDomainListData = requesting; }
122 bool getPrevRequestsDomainListData() {
return _prevRequestsDomainListData; }
123 void setPrevRequestsDomainListData(
bool requesting) { _prevRequestsDomainListData = requesting; }
125 const ConicalViewFrustums& getViewFrustums()
const {
return _currentViewFrustums; }
127 uint64_t getLastOtherAvatarEncodeTime(NLPacket::LocalID otherAvatar)
const;
128 void setLastOtherAvatarEncodeTime(NLPacket::LocalID otherAvatar, uint64_t time);
130 QVector<JointData>& getLastOtherAvatarSentJoints(NLPacket::LocalID otherAvatar) {
return _lastOtherAvatarSentJoints[otherAvatar]; }
132 void queuePacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer node);
133 int processPackets(
const SlaveSharedData& slaveSharedData);
135 void processSetTraitsMessage(ReceivedMessage& message,
const SlaveSharedData& slaveSharedData, Node& sendingNode);
136 void emulateDeleteEntitiesTraitsMessage(
const QList<QUuid>& avatarEntityIDs);
137 void processBulkAvatarTraitsAckMessage(ReceivedMessage& message);
138 void checkSkeletonURLAgainstWhitelist(
const SlaveSharedData& slaveSharedData, Node& sendingNode,
139 AvatarTraits::TraitVersion traitVersion);
141 using TraitsCheckTimestamp = std::chrono::steady_clock::time_point;
143 TraitsCheckTimestamp getLastReceivedTraitsChange()
const {
return _lastReceivedTraitsChange; }
145 AvatarTraits::TraitVersions& getLastReceivedTraitVersions() {
return _lastReceivedTraitVersions; }
146 const AvatarTraits::TraitVersions& getLastReceivedTraitVersions()
const {
return _lastReceivedTraitVersions; }
148 TraitsCheckTimestamp getLastOtherAvatarTraitsSendPoint(Node::LocalID otherAvatar)
const;
149 void setLastOtherAvatarTraitsSendPoint(Node::LocalID otherAvatar, TraitsCheckTimestamp sendPoint)
150 { _lastSentTraitsTimestamps[otherAvatar] = sendPoint; }
152 AvatarTraits::TraitMessageSequence getTraitsMessageSequence()
const {
return _currentTraitsMessageSequence; }
153 AvatarTraits::TraitMessageSequence nextTraitsMessageSequence() {
return ++_currentTraitsMessageSequence; }
154 AvatarTraits::TraitVersions& getPendingTraitVersions(AvatarTraits::TraitMessageSequence seq, Node::LocalID otherId) {
155 return _perNodePendingTraitVersions[seq][otherId];
158 AvatarTraits::TraitVersions& getLastSentTraitVersions(Node::LocalID otherAvatar) {
return _perNodeSentTraitVersions[otherAvatar]; }
159 AvatarTraits::TraitVersions& getLastAckedTraitVersions(Node::LocalID otherAvatar) {
return _perNodeAckedTraitVersions[otherAvatar]; }
161 void resetSentTraitData(Node::LocalID nodeID);
164 struct PacketQueue :
public std::queue<QSharedPointer<ReceivedMessage>> {
165 QWeakPointer<Node> node;
167 PacketQueue _packetQueue;
169 MixerAvatarSharedPointer _avatar {
new MixerAvatar() };
171 uint16_t _lastReceivedSequenceNumber { 0 };
172 std::unordered_map<NLPacket::LocalID, uint16_t> _lastBroadcastSequenceNumbers;
173 std::unordered_map<NLPacket::LocalID, uint64_t> _lastBroadcastTimes;
177 std::unordered_map<NLPacket::LocalID, uint64_t> _lastOtherAvatarEncodeTime;
178 std::unordered_map<NLPacket::LocalID, QVector<JointData>> _lastOtherAvatarSentJoints;
180 uint64_t _identityChangeTimestamp;
181 bool _avatarSessionDisplayNameMustChange{
true };
182 bool _avatarSkeletonModelUrlMustChange{
false };
184 int _numAvatarsSentLastFrame = 0;
185 int _numFramesSinceAdjustment = 0;
187 SimpleMovingAverage _otherAvatarStarves;
188 SimpleMovingAverage _otherAvatarSkips;
189 int _numOutOfOrderSends = 0;
191 SimpleMovingAverage _avgOtherAvatarDataRate;
192 SimpleMovingAverage _avgOtherAvatarTraitsRate;
193 std::vector<QUuid> _radiusIgnoredOthers;
194 ConicalViewFrustums _currentViewFrustums;
196 int _recentOtherAvatarsInView { 0 };
197 int _recentOtherAvatarsOutOfView { 0 };
198 QString _baseDisplayName{};
199 bool _requestsDomainListData {
false };
200 bool _prevRequestsDomainListData{
false };
202 AvatarTraits::TraitVersions _lastReceivedTraitVersions;
203 TraitsCheckTimestamp _lastReceivedTraitsChange;
205 AvatarTraits::TraitMessageSequence _currentTraitsMessageSequence{ 0 };
213 std::unordered_map<AvatarTraits::TraitMessageSequence, PerNodeTraitVersions> _perNodePendingTraitVersions;
219 PerNodeTraitVersions _perNodeAckedTraitVersions;
221 std::unordered_map<Node::LocalID, TraitsCheckTimestamp> _lastSentTraitsTimestamps;
225 PerNodeTraitVersions _perNodeSentTraitVersions;
227 std::atomic_bool _isIgnoreRadiusEnabled {
false };