mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 06:29:30 +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),
|
_voxelImporter(_window),
|
||||||
_wantToKillLocalVoxels(false),
|
_wantToKillLocalVoxels(false),
|
||||||
_audioScope(256, 200, true),
|
_audioScope(256, 200, true),
|
||||||
|
_avatarManager(),
|
||||||
_profile(QString()),
|
_profile(QString()),
|
||||||
_mirrorViewRect(QRect(MIRROR_VIEW_LEFT_PADDING, MIRROR_VIEW_TOP_PADDING, MIRROR_VIEW_WIDTH, MIRROR_VIEW_HEIGHT)),
|
_mirrorViewRect(QRect(MIRROR_VIEW_LEFT_PADDING, MIRROR_VIEW_TOP_PADDING, MIRROR_VIEW_WIDTH, MIRROR_VIEW_HEIGHT)),
|
||||||
_mouseX(0),
|
_mouseX(0),
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
#include "VoxelSystem.h"
|
#include "VoxelSystem.h"
|
||||||
#include "VoxelImporter.h"
|
#include "VoxelImporter.h"
|
||||||
#include "avatar/Avatar.h"
|
#include "avatar/Avatar.h"
|
||||||
|
#include "avatar/AvatarManager.h"
|
||||||
#include "avatar/MyAvatar.h"
|
#include "avatar/MyAvatar.h"
|
||||||
#include "avatar/Profile.h"
|
#include "avatar/Profile.h"
|
||||||
#include "devices/Faceshift.h"
|
#include "devices/Faceshift.h"
|
||||||
|
@ -167,7 +168,7 @@ public:
|
||||||
GlowEffect* getGlowEffect() { return &_glowEffect; }
|
GlowEffect* getGlowEffect() { return &_glowEffect; }
|
||||||
|
|
||||||
Avatar* getLookatTargetAvatar() const { return _lookatTargetAvatar; }
|
Avatar* getLookatTargetAvatar() const { return _lookatTargetAvatar; }
|
||||||
|
AvatarManager& getAvatarManager() { return _avatarManager; }
|
||||||
Profile* getProfile() { return &_profile; }
|
Profile* getProfile() { return &_profile; }
|
||||||
void resetProfile(const QString& username);
|
void resetProfile(const QString& username);
|
||||||
|
|
||||||
|
@ -227,15 +228,13 @@ public slots:
|
||||||
void initAvatarAndViewFrustum();
|
void initAvatarAndViewFrustum();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
void timer();
|
void timer();
|
||||||
void idle();
|
void idle();
|
||||||
void terminate();
|
void terminate();
|
||||||
|
|
||||||
void setFullscreen(bool fullscreen);
|
void setFullscreen(bool fullscreen);
|
||||||
void setEnable3DTVMode(bool enable3DTVMode);
|
void setEnable3DTVMode(bool enable3DTVMode);
|
||||||
|
|
||||||
|
|
||||||
void renderThrustAtVoxel(const glm::vec3& thrust);
|
void renderThrustAtVoxel(const glm::vec3& thrust);
|
||||||
|
|
||||||
void renderCoverageMap();
|
void renderCoverageMap();
|
||||||
|
@ -372,6 +371,7 @@ private:
|
||||||
|
|
||||||
VoxelQuery _voxelQuery; // NodeData derived class for querying voxels from voxel server
|
VoxelQuery _voxelQuery; // NodeData derived class for querying voxels from voxel server
|
||||||
|
|
||||||
|
AvatarManager _avatarManager;
|
||||||
MyAvatar _myAvatar; // The rendered avatar of oneself
|
MyAvatar _myAvatar; // The rendered avatar of oneself
|
||||||
Profile _profile; // The data-server linked profile for this user
|
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),
|
application->_metavoxels.processData(QByteArray((const char*) incomingPacket, bytesReceived),
|
||||||
senderSockAddr);
|
senderSockAddr);
|
||||||
break;
|
break;
|
||||||
case PACKET_TYPE_BULK_AVATAR_DATA:
|
case PACKET_TYPE_BULK_AVATAR_DATA: {
|
||||||
NodeList::getInstance()->processBulkNodeData(senderSockAddr,
|
// update having heard from the avatar-mixer and record the bytes received
|
||||||
incomingPacket,
|
SharedNodePointer avatarMixer = NodeList::getInstance()->nodeWithAddress(senderSockAddr);
|
||||||
bytesReceived);
|
|
||||||
|
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);
|
application->_bandwidthMeter.inputStream(BandwidthMeter::AVATARS).updateValue(bytesReceived);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case PACKET_TYPE_DATA_SERVER_GET:
|
case PACKET_TYPE_DATA_SERVER_GET:
|
||||||
case PACKET_TYPE_DATA_SERVER_PUT:
|
case PACKET_TYPE_DATA_SERVER_PUT:
|
||||||
case PACKET_TYPE_DATA_SERVER_SEND:
|
case PACKET_TYPE_DATA_SERVER_SEND:
|
||||||
|
|
|
@ -111,7 +111,7 @@ public:
|
||||||
/// \return whether or not the sphere collided
|
/// \return whether or not the sphere collided
|
||||||
virtual bool findSphereCollision(const glm::vec3& sphereCenter, float sphereRadius, CollisionInfo& collision);
|
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);
|
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) {
|
int NodeList::updateNodeWithData(Node *node, const HifiSockAddr& senderSockAddr, unsigned char *packetData, int dataBytes) {
|
||||||
QMutexLocker locker(&node->getMutex());
|
QMutexLocker locker(&node->getMutex());
|
||||||
|
|
||||||
|
|
|
@ -111,7 +111,6 @@ public:
|
||||||
SharedNodePointer addOrUpdateNode(const QUuid& uuid, char nodeType, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket);
|
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 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);
|
int updateNodeWithData(Node *node, const HifiSockAddr& senderSockAddr, unsigned char *packetData, int dataBytes);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue