mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-04 15:13:10 +02:00
add an AvatarManager that will keep Avatars in Application thread
This commit is contained in:
parent
9a8e978733
commit
a9f1984676
8 changed files with 102 additions and 53 deletions
|
@ -116,6 +116,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
|
|||
_voxelImporter(_window),
|
||||
_wantToKillLocalVoxels(false),
|
||||
_audioScope(256, 200, true),
|
||||
_avatarManager(),
|
||||
_profile(QString()),
|
||||
_mirrorViewRect(QRect(MIRROR_VIEW_LEFT_PADDING, MIRROR_VIEW_TOP_PADDING, MIRROR_VIEW_WIDTH, MIRROR_VIEW_HEIGHT)),
|
||||
_mouseX(0),
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include "VoxelSystem.h"
|
||||
#include "VoxelImporter.h"
|
||||
#include "avatar/Avatar.h"
|
||||
#include "avatar/AvatarManager.h"
|
||||
#include "avatar/MyAvatar.h"
|
||||
#include "avatar/Profile.h"
|
||||
#include "devices/Faceshift.h"
|
||||
|
@ -167,7 +168,7 @@ public:
|
|||
GlowEffect* getGlowEffect() { return &_glowEffect; }
|
||||
|
||||
Avatar* getLookatTargetAvatar() const { return _lookatTargetAvatar; }
|
||||
|
||||
AvatarManager& getAvatarManager() { return _avatarManager; }
|
||||
Profile* getProfile() { return &_profile; }
|
||||
void resetProfile(const QString& username);
|
||||
|
||||
|
@ -227,15 +228,13 @@ public slots:
|
|||
void initAvatarAndViewFrustum();
|
||||
|
||||
private slots:
|
||||
|
||||
void timer();
|
||||
void idle();
|
||||
void terminate();
|
||||
|
||||
void setFullscreen(bool fullscreen);
|
||||
void setEnable3DTVMode(bool enable3DTVMode);
|
||||
|
||||
|
||||
|
||||
void renderThrustAtVoxel(const glm::vec3& thrust);
|
||||
|
||||
void renderCoverageMap();
|
||||
|
@ -372,6 +371,7 @@ private:
|
|||
|
||||
VoxelQuery _voxelQuery; // NodeData derived class for querying voxels from voxel server
|
||||
|
||||
AvatarManager _avatarManager;
|
||||
MyAvatar _myAvatar; // The rendered avatar of oneself
|
||||
Profile _profile; // The data-server linked profile for this user
|
||||
|
||||
|
|
|
@ -89,12 +89,23 @@ void DatagramProcessor::processDatagrams() {
|
|||
application->_metavoxels.processData(QByteArray((const char*) incomingPacket, bytesReceived),
|
||||
senderSockAddr);
|
||||
break;
|
||||
case PACKET_TYPE_BULK_AVATAR_DATA:
|
||||
NodeList::getInstance()->processBulkNodeData(senderSockAddr,
|
||||
incomingPacket,
|
||||
bytesReceived);
|
||||
case PACKET_TYPE_BULK_AVATAR_DATA: {
|
||||
// update having heard from the avatar-mixer and record the bytes received
|
||||
SharedNodePointer avatarMixer = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
|
||||
|
||||
if (avatarMixer) {
|
||||
avatarMixer->setLastHeardMicrostamp(usecTimestampNow());
|
||||
avatarMixer->recordBytesReceived(bytesReceived);
|
||||
|
||||
|
||||
QMetaObject::invokeMethod(&application->getAvatarManager(), "processAvatarMixerDatagram",
|
||||
Q_ARG(const QByteArray&,
|
||||
QByteArray(reinterpret_cast<char*>(incomingPacket), bytesReceived)));
|
||||
}
|
||||
|
||||
application->_bandwidthMeter.inputStream(BandwidthMeter::AVATARS).updateValue(bytesReceived);
|
||||
break;
|
||||
}
|
||||
case PACKET_TYPE_DATA_SERVER_GET:
|
||||
case PACKET_TYPE_DATA_SERVER_PUT:
|
||||
case PACKET_TYPE_DATA_SERVER_SEND:
|
||||
|
|
|
@ -111,7 +111,7 @@ public:
|
|||
/// \return whether or not the sphere collided
|
||||
virtual bool findSphereCollision(const glm::vec3& sphereCenter, float sphereRadius, CollisionInfo& collision);
|
||||
|
||||
virtual int parseData(unsigned char* sourceBuffer, int numBytes);
|
||||
int parseData(unsigned char* sourceBuffer, int numBytes);
|
||||
|
||||
static void renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, float radius1, float radius2);
|
||||
|
||||
|
|
54
interface/src/avatar/AvatarManager.cpp
Normal file
54
interface/src/avatar/AvatarManager.cpp
Normal file
|
@ -0,0 +1,54 @@
|
|||
//
|
||||
// AvatarManager.cpp
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 1/23/2014.
|
||||
// Copyright (c) 2014 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include <UUID.h>
|
||||
|
||||
#include "Avatar.h"
|
||||
|
||||
#include "AvatarManager.h"
|
||||
|
||||
AvatarManager::AvatarManager(QObject* parent) :
|
||||
_hash()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void AvatarManager::processAvatarMixerDatagram(const QByteArray& datagram) {
|
||||
unsigned char packetData[MAX_PACKET_SIZE];
|
||||
memcpy(packetData, datagram.data(), datagram.size());
|
||||
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(packetData);
|
||||
|
||||
QUuid nodeUUID = QUuid::fromRfc4122(datagram.mid(numBytesPacketHeader, NUM_BYTES_RFC4122_UUID));
|
||||
|
||||
int bytesRead = numBytesPacketHeader;
|
||||
|
||||
unsigned char avatarData[MAX_PACKET_SIZE];
|
||||
populateTypeAndVersion(avatarData, PACKET_TYPE_HEAD_DATA);
|
||||
|
||||
while (bytesRead < datagram.size()) {
|
||||
Avatar* matchingAvatar = _hash.value(nodeUUID);
|
||||
|
||||
if (!matchingAvatar) {
|
||||
// construct a new Avatar for this node
|
||||
matchingAvatar = new Avatar();
|
||||
|
||||
// insert the new avatar into our hash
|
||||
_hash.insert(nodeUUID, matchingAvatar);
|
||||
|
||||
qDebug() << "Adding avatar with UUID" << nodeUUID << "to AvatarManager hash.";
|
||||
}
|
||||
|
||||
// copy the rest of the packet to the avatarData holder so we can read the next Avatar from there
|
||||
memcpy(avatarData, packetData + bytesRead, datagram.size() - bytesRead);
|
||||
|
||||
// have the matching (or new) avatar parse the data from the packet
|
||||
bytesRead += matchingAvatar->parseData(avatarData,
|
||||
datagram.size() - bytesRead);
|
||||
}
|
||||
}
|
27
interface/src/avatar/AvatarManager.h
Normal file
27
interface/src/avatar/AvatarManager.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
//
|
||||
// AvatarManager.h
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 1/23/2014.
|
||||
// Copyright (c) 2014 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef __hifi__AvatarManager__
|
||||
#define __hifi__AvatarManager__
|
||||
|
||||
#include <QtCore/QHash>
|
||||
#include <QtCore/QObject>
|
||||
|
||||
#include "Avatar.h"
|
||||
|
||||
class AvatarManager : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
AvatarManager(QObject* parent = 0);
|
||||
public slots:
|
||||
void processAvatarMixerDatagram(const QByteArray& datagram);
|
||||
private:
|
||||
QHash<QUuid, Avatar*> _hash;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__AvatarManager__) */
|
|
@ -187,49 +187,6 @@ void NodeList::processNodeData(const HifiSockAddr& senderSockAddr, unsigned char
|
|||
}
|
||||
}
|
||||
|
||||
void NodeList::processBulkNodeData(const HifiSockAddr& senderAddress, unsigned char *packetData, int numTotalBytes) {
|
||||
SharedNodePointer bulkSendNode = nodeWithAddress(senderAddress);
|
||||
|
||||
// find the avatar mixer in our node list and update the lastRecvTime from it
|
||||
if (bulkSendNode) {
|
||||
|
||||
bulkSendNode->setLastHeardMicrostamp(usecTimestampNow());
|
||||
bulkSendNode->recordBytesReceived(numTotalBytes);
|
||||
|
||||
int numBytesPacketHeader = numBytesForPacketHeader(packetData);
|
||||
|
||||
unsigned char* startPosition = packetData;
|
||||
unsigned char* currentPosition = startPosition + numBytesPacketHeader;
|
||||
unsigned char* packetHolder = new unsigned char[numTotalBytes];
|
||||
|
||||
// we've already verified packet version for the bulk packet, so all head data in the packet is also up to date
|
||||
populateTypeAndVersion(packetHolder, PACKET_TYPE_HEAD_DATA);
|
||||
|
||||
while ((currentPosition - startPosition) < numTotalBytes) {
|
||||
|
||||
memcpy(packetHolder + numBytesPacketHeader,
|
||||
currentPosition,
|
||||
numTotalBytes - (currentPosition - startPosition));
|
||||
|
||||
QUuid nodeUUID = QUuid::fromRfc4122(QByteArray((char*)currentPosition, NUM_BYTES_RFC4122_UUID));
|
||||
SharedNodePointer matchingNode = nodeWithUUID(nodeUUID);
|
||||
|
||||
if (!matchingNode) {
|
||||
// we're missing this node, we need to add it to the list
|
||||
matchingNode = addOrUpdateNode(nodeUUID, NODE_TYPE_AGENT, HifiSockAddr(), HifiSockAddr());
|
||||
}
|
||||
|
||||
currentPosition += updateNodeWithData(matchingNode.data(),
|
||||
HifiSockAddr(),
|
||||
packetHolder,
|
||||
numTotalBytes - (currentPosition - startPosition));
|
||||
|
||||
}
|
||||
|
||||
delete[] packetHolder;
|
||||
}
|
||||
}
|
||||
|
||||
int NodeList::updateNodeWithData(Node *node, const HifiSockAddr& senderSockAddr, unsigned char *packetData, int dataBytes) {
|
||||
QMutexLocker locker(&node->getMutex());
|
||||
|
||||
|
|
|
@ -111,7 +111,6 @@ public:
|
|||
SharedNodePointer addOrUpdateNode(const QUuid& uuid, char nodeType, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket);
|
||||
|
||||
void processNodeData(const HifiSockAddr& senderSockAddr, unsigned char *packetData, size_t dataBytes);
|
||||
void processBulkNodeData(const HifiSockAddr& senderSockAddr, unsigned char *packetData, int numTotalBytes);
|
||||
|
||||
int updateNodeWithData(Node *node, const HifiSockAddr& senderSockAddr, unsigned char *packetData, int dataBytes);
|
||||
|
||||
|
|
Loading…
Reference in a new issue