Refactoring and cleaning

This commit is contained in:
luiscuenca 2018-08-23 15:52:42 -07:00
parent e3ad5adcae
commit 3d959ca7ee
5 changed files with 223 additions and 53 deletions

View file

@ -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

View file

@ -918,7 +918,26 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) {
PACKET_READ_CHECK(AvatarGlobalPosition, sizeof(AvatarDataPacket::AvatarGlobalPosition));
auto data = reinterpret_cast<const AvatarDataPacket::AvatarGlobalPosition*>(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<quint64>(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();

View file

@ -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> _clientTraitsHandler;

View file

@ -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<AvatarSharedPointer> emptyReplicas = std::vector<AvatarSharedPointer>();
_replicasMap.insert(std::pair<QUuid, std::vector<AvatarSharedPointer>>(parentID, emptyReplicas));
}
auto &replicas = _replicasMap[parentID];
replica->setReplicaIndex((int)replicas.size() + 1);
replicas.push_back(replica);
}
std::vector<QUuid> AvatarReplicas::getReplicaIDs(const QUuid& parentID, int count) {
std::vector<QUuid> 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<NodeList>();
@ -138,40 +211,28 @@ AvatarSharedPointer AvatarHashMap::parseAvatarData(QSharedPointer<ReceivedMessag
// make sure this isn't our own avatar data or for a previously ignored node
auto nodeList = DependencyManager::get<NodeList>();
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<QUuid> 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<QUuid, std::vector<QUuid>>(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<ReceivedMessage>
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<ReceivedMessage> message, SharedNodePointer sendingNode) {
void AvatarHashMap::processBulkAvatarTraitsForID(QUuid sessionUUID, QSharedPointer<ReceivedMessage> 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<Receiv
}
void AvatarHashMap::processBulkAvatarTraits(QSharedPointer<ReceivedMessage> 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<ReceivedMessage> 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<ReceivedMessage> 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) {

View file

@ -41,6 +41,24 @@
* @hifi-assignment-client
*/
class AvatarReplicas {
public:
AvatarReplicas() {};
void addReplica(const QUuid& parentID, AvatarSharedPointer replica);
std::vector<QUuid> 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<QUuid, std::vector<AvatarSharedPointer>> _replicasMap;
};
class AvatarHashMap : public QObject, public Dependency {
Q_OBJECT
SINGLETON_DEPENDENCY
@ -134,7 +152,7 @@ protected slots:
*/
void processAvatarIdentityPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
void processAvatarTraits(QUuid sessionUUID, QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
void processBulkAvatarTraitsForID(QUuid sessionUUID, QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
void processBulkAvatarTraits(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
/**jsdoc
@ -168,7 +186,8 @@ protected:
mutable QReadWriteLock _hashLock;
std::unordered_map<QUuid, AvatarTraits::TraitVersions> _processedTraitVersions;
std::map<QUuid, std::vector<QUuid>> _surrogates;
AvatarReplicas _replicas;
private:
QUuid _lastOwnerSessionUUID;
};