Basic sharing of the avatar voxel URLs.

This commit is contained in:
Andrzej Kapolka 2013-06-05 14:55:49 -07:00
parent 69dd4ff59b
commit a4aa8e7bde
5 changed files with 76 additions and 6 deletions

View file

@ -105,6 +105,17 @@ int main(int argc, const char* argv[]) {
agentList->getAgentSocket()->send(agentAddress, broadcastPacket, currentBufferPosition - broadcastPacket);
break;
case PACKET_HEADER_AVATAR_VOXEL_URL:
// grab the agent ID from the packet
unpackAgentId(packetData + 1, &agentID);
// let everyone else know about the update
for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) {
if (agent->getActiveSocket() && agent->getAgentID() != agentID) {
agentList->getAgentSocket()->send(agent->getActiveSocket(), packetData, receivedBytes);
}
}
break;
case PACKET_HEADER_DOMAIN:
// ignore the DS packet, for now agents are added only when they communicate directly with us

View file

@ -983,6 +983,44 @@ void Application::terminate() {
}
}
static void sendAvatarVoxelURLMessage(const QUrl& url) {
uint16_t ownerID = AgentList::getInstance()->getOwnerID();
if (ownerID == UNKNOWN_AGENT_ID) {
return; // we don't yet know who we are
}
QByteArray message;
message.append(PACKET_HEADER_AVATAR_VOXEL_URL);
message.append((const char*)&ownerID, sizeof(ownerID));
message.append(url.toEncoded());
AgentList::getInstance()->broadcastToAgents((unsigned char*)message.data(), message.size(), &AGENT_TYPE_AVATAR_MIXER, 1);
}
static void processAvatarVoxelURLMessage(unsigned char *packetData, size_t dataBytes) {
// skip the header
packetData++;
dataBytes--;
// read the agent id
uint16_t agentID = *(uint16_t*)packetData;
packetData += sizeof(agentID);
dataBytes -= sizeof(agentID);
// make sure the agent exists
Agent* agent = AgentList::getInstance()->agentWithID(agentID);
if (!agent || !agent->getLinkedData()) {
return;
}
Avatar* avatar = static_cast<Avatar*>(agent->getLinkedData());
if (!avatar->isInitialized()) {
return; // wait until initialized
}
QUrl url = QUrl::fromEncoded(QByteArray::fromRawData((char*)packetData, dataBytes));
// invoke the set URL function on the simulate/render thread
QMetaObject::invokeMethod(avatar->getVoxels(), "setVoxelURL", Q_ARG(QUrl, url));
}
void Application::editPreferences() {
QDialog dialog(_glWidget);
dialog.setWindowTitle("Interface Preferences");
@ -1006,7 +1044,8 @@ void Application::editPreferences() {
}
QUrl url(avatarURL->text());
_settings->setValue("avatarURL", url);
_myAvatar.getVoxels()->loadVoxelsFromURL(url);
_myAvatar.getVoxels()->setVoxelURL(url);
sendAvatarVoxelURLMessage(url);
}
void Application::pair() {
@ -1507,7 +1546,9 @@ void Application::init() {
_myCamera.setModeShiftRate(1.0f);
_myAvatar.setDisplayingLookatVectors(false);
_myAvatar.getVoxels()->loadVoxelsFromURL(_settings->value("avatarURL").toUrl());
QUrl avatarURL = _settings->value("avatarURL").toUrl();
_myAvatar.getVoxels()->setVoxelURL(avatarURL);
sendAvatarVoxelURLMessage(avatarURL);
QCursor::setPos(_headMouseX, _headMouseY);
@ -1599,6 +1640,12 @@ void Application::updateAvatar(float deltaTime) {
const char broadcastReceivers[2] = {AGENT_TYPE_VOXEL, AGENT_TYPE_AVATAR_MIXER};
AgentList::getInstance()->broadcastToAgents(broadcastString, endOfBroadcastStringWrite - broadcastString, broadcastReceivers, sizeof(broadcastReceivers));
// once in a while, send my voxel url
const float AVATAR_VOXEL_URL_SEND_INTERVAL = 1.0f; // seconds
if (shouldDo(AVATAR_VOXEL_URL_SEND_INTERVAL, deltaTime)) {
sendAvatarVoxelURLMessage(_myAvatar.getVoxels()->getVoxelURL());
}
}
// If I'm in paint mode, send a voxel out to VOXEL server agents.
@ -2435,6 +2482,9 @@ void* Application::networkReceive(void* args) {
app->_incomingPacket,
bytesReceived);
break;
case PACKET_HEADER_AVATAR_VOXEL_URL:
processAvatarVoxelURLMessage(app->_incomingPacket, bytesReceived);
break;
default:
AgentList::getInstance()->processAgentData(&senderAddress, app->_incomingPacket, bytesReceived);
break;

View file

@ -8,7 +8,6 @@
#include <cstring>
#include <QNetworkReply>
#include <QUrl>
#include <GeometryUtil.h>
@ -24,6 +23,9 @@ const int BONE_ELEMENTS_PER_VOXEL = BONE_ELEMENTS_PER_VERTEX * VERTICES_PER_VOXE
AvatarVoxelSystem::AvatarVoxelSystem(Avatar* avatar) :
VoxelSystem(AVATAR_TREE_SCALE, MAX_VOXELS_PER_AVATAR),
_avatar(avatar), _voxelReply(0) {
// we may have been created in the network thread, but we live in the main thread
moveToThread(Application::getInstance()->thread());
}
AvatarVoxelSystem::~AvatarVoxelSystem() {
@ -75,7 +77,7 @@ void AvatarVoxelSystem::removeOutOfView() {
// no-op for now
}
void AvatarVoxelSystem::loadVoxelsFromURL(const QUrl& url) {
void AvatarVoxelSystem::setVoxelURL(const QUrl& url) {
// cancel any current download
if (_voxelReply != 0) {
delete _voxelReply;
@ -84,6 +86,9 @@ void AvatarVoxelSystem::loadVoxelsFromURL(const QUrl& url) {
killLocalVoxels();
// remember the URL
_voxelURL = url;
// handle "file://" urls...
if (url.isLocalFile()) {
QString pathString = url.path();

View file

@ -10,6 +10,7 @@
#define __interface__AvatarVoxelSystem__
#include <QObject>
#include <QUrl>
#include "VoxelSystem.h"
@ -17,7 +18,6 @@ const int BONE_ELEMENTS_PER_VERTEX = 4;
typedef GLubyte BoneIndices[BONE_ELEMENTS_PER_VERTEX];
class QNetworkReply;
class QUrl;
class Avatar;
@ -33,7 +33,8 @@ public:
virtual void removeOutOfView();
void loadVoxelsFromURL(const QUrl& url);
Q_INVOKABLE void setVoxelURL(const QUrl& url);
const QUrl& getVoxelURL() const { return _voxelURL; }
protected:
@ -55,6 +56,8 @@ private:
Avatar* _avatar;
QUrl _voxelURL;
GLubyte* _readBoneIndicesArray;
GLfloat* _readBoneWeightsArray;
GLubyte* _writeBoneIndicesArray;

View file

@ -27,6 +27,7 @@ const PACKET_HEADER PACKET_HEADER_ERASE_VOXEL = 'E';
const PACKET_HEADER PACKET_HEADER_VOXEL_DATA = 'V';
const PACKET_HEADER PACKET_HEADER_VOXEL_DATA_MONOCHROME = 'v';
const PACKET_HEADER PACKET_HEADER_BULK_AVATAR_DATA = 'X';
const PACKET_HEADER PACKET_HEADER_AVATAR_VOXEL_URL = 'U';
const PACKET_HEADER PACKET_HEADER_TRANSMITTER_DATA_V2 = 'T';
const PACKET_HEADER PACKET_HEADER_ENVIRONMENT_DATA = 'e';
const PACKET_HEADER PACKET_HEADER_DOMAIN_LIST_REQUEST = 'L';