mirror of
https://github.com/overte-org/overte.git
synced 2025-04-19 13:43:49 +02:00
Refactoring and cleaning
This commit is contained in:
parent
e3ad5adcae
commit
3d959ca7ee
5 changed files with 223 additions and 53 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue