mirror of
https://github.com/lubosz/overte.git
synced 2025-04-08 09:43:01 +02:00
Merge pull request #1029 from birarda/nameserver
initial revision of storing user data in data-server
This commit is contained in:
commit
3a92856386
21 changed files with 519 additions and 78 deletions
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include <AvatarData.h>
|
||||
#include <NodeList.h>
|
||||
#include <UUID.h>
|
||||
#include <VoxelConstants.h>
|
||||
|
||||
#include "Agent.h"
|
||||
|
@ -50,7 +51,7 @@ void Agent::run() {
|
|||
// figure out the URL for the script for this agent assignment
|
||||
QString scriptURLString("http://%1:8080/assignment/%2");
|
||||
scriptURLString = scriptURLString.arg(NodeList::getInstance()->getDomainIP().toString(),
|
||||
this->getUUIDStringWithoutCurlyBraces());
|
||||
uuidStringWithoutCurlyBraces(_uuid));
|
||||
|
||||
// setup curl for script download
|
||||
CURLcode curlResult;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include <PacketHeaders.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <UUID.h>
|
||||
|
||||
#include "DomainServer.h"
|
||||
|
||||
|
@ -62,7 +63,7 @@ void DomainServer::civetwebUploadHandler(struct mg_connection *connection, const
|
|||
QString newPath(ASSIGNMENT_SCRIPT_HOST_LOCATION);
|
||||
newPath += "/";
|
||||
// append the UUID for this script as the new filename, remove the curly braces
|
||||
newPath += scriptAssignment->getUUIDStringWithoutCurlyBraces();
|
||||
newPath += uuidStringWithoutCurlyBraces(scriptAssignment->getUUID());
|
||||
|
||||
// rename the saved script to the GUID of the assignment and move it to the script host locaiton
|
||||
rename(path, newPath.toLocal8Bit().constData());
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
#include <VoxelSceneStats.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "DataServerClient.h"
|
||||
#include "LogDisplay.h"
|
||||
#include "Menu.h"
|
||||
#include "Swatch.h"
|
||||
|
@ -1260,13 +1261,14 @@ void Application::processAvatarURLsMessage(unsigned char* packetData, size_t dat
|
|||
return;
|
||||
}
|
||||
QDataStream in(QByteArray((char*)packetData, dataBytes));
|
||||
QUrl voxelURL, faceURL;
|
||||
QUrl voxelURL;
|
||||
in >> voxelURL;
|
||||
in >> faceURL;
|
||||
|
||||
// invoke the set URL functions on the simulate/render thread
|
||||
QMetaObject::invokeMethod(avatar->getVoxels(), "setVoxelURL", Q_ARG(QUrl, voxelURL));
|
||||
QMetaObject::invokeMethod(&avatar->getHead().getBlendFace(), "setModelURL", Q_ARG(QUrl, faceURL));
|
||||
|
||||
// use this timing to as the data-server for an updated mesh for this avatar (if we have UUID)
|
||||
DataServerClient::getValueForKeyAndUUID(DataServerKey::FaceMeshURL, avatar->getUUID());
|
||||
}
|
||||
|
||||
void Application::processAvatarFaceVideoMessage(unsigned char* packetData, size_t dataBytes) {
|
||||
|
@ -1593,6 +1595,11 @@ void Application::init() {
|
|||
_audio.setJitterBufferSamples(Menu::getInstance()->getAudioJitterBufferSamples());
|
||||
}
|
||||
qDebug("Loaded settings.\n");
|
||||
|
||||
if (!_profile.getUsername().isEmpty()) {
|
||||
// we have a username for this avatar, ask the data-server for the mesh URL for this avatar
|
||||
DataServerClient::getClientValueForKey(DataServerKey::FaceMeshURL);
|
||||
}
|
||||
|
||||
// Set up VoxelSystem after loading preferences so we can get the desired max voxel count
|
||||
_voxels.setMaxVoxels(Menu::getInstance()->getMaxVoxels());
|
||||
|
@ -1602,7 +1609,7 @@ void Application::init() {
|
|||
_voxels.init();
|
||||
|
||||
|
||||
Avatar::sendAvatarURLsMessage(_myAvatar.getVoxels()->getVoxelURL(), _myAvatar.getHead().getBlendFace().getModelURL());
|
||||
Avatar::sendAvatarURLsMessage(_myAvatar.getVoxels()->getVoxelURL());
|
||||
|
||||
_palette.init(_glWidget->width(), _glWidget->height());
|
||||
_palette.addAction(Menu::getInstance()->getActionForOption(MenuOption::VoxelAddMode), 0, 0);
|
||||
|
@ -2177,8 +2184,7 @@ void Application::updateAvatar(float deltaTime) {
|
|||
// once in a while, send my urls
|
||||
const float AVATAR_URLS_SEND_INTERVAL = 1.0f; // seconds
|
||||
if (shouldDo(AVATAR_URLS_SEND_INTERVAL, deltaTime)) {
|
||||
Avatar::sendAvatarURLsMessage(_myAvatar.getVoxels()->getVoxelURL(),
|
||||
_myAvatar.getHead().getBlendFace().getModelURL());
|
||||
Avatar::sendAvatarURLsMessage(_myAvatar.getVoxels()->getVoxelURL());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3616,6 +3622,12 @@ void* Application::networkReceive(void* args) {
|
|||
case PACKET_TYPE_AVATAR_FACE_VIDEO:
|
||||
processAvatarFaceVideoMessage(app->_incomingPacket, bytesReceived);
|
||||
break;
|
||||
case PACKET_TYPE_DATA_SERVER_GET:
|
||||
case PACKET_TYPE_DATA_SERVER_PUT:
|
||||
case PACKET_TYPE_DATA_SERVER_SEND:
|
||||
case PACKET_TYPE_DATA_SERVER_CONFIRM:
|
||||
DataServerClient::processMessageFromDataServer(app->_incomingPacket, bytesReceived);
|
||||
break;
|
||||
default:
|
||||
NodeList::getInstance()->processNodeData(&senderAddress, app->_incomingPacket, bytesReceived);
|
||||
break;
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "VoxelImporter.h"
|
||||
#include "avatar/Avatar.h"
|
||||
#include "avatar/MyAvatar.h"
|
||||
#include "avatar/Profile.h"
|
||||
#include "avatar/HandControl.h"
|
||||
#include "devices/Faceshift.h"
|
||||
#include "devices/SerialInterface.h"
|
||||
|
@ -110,6 +111,7 @@ public:
|
|||
|
||||
QGLWidget* getGLWidget() { return _glWidget; }
|
||||
MyAvatar* getAvatar() { return &_myAvatar; }
|
||||
Profile* getProfile() { return &_profile; }
|
||||
Audio* getAudio() { return &_audio; }
|
||||
Camera* getCamera() { return &_myCamera; }
|
||||
ViewFrustum* getViewFrustum() { return &_viewFrustum; }
|
||||
|
@ -275,6 +277,7 @@ private:
|
|||
Oscilloscope _audioScope;
|
||||
|
||||
MyAvatar _myAvatar; // The rendered avatar of oneself
|
||||
Profile _profile; // The data-server linked profile for this user
|
||||
|
||||
Transmitter _myTransmitter; // Gets UDP data from transmitter app used to animate the avatar
|
||||
|
||||
|
|
197
interface/src/DataServerClient.cpp
Normal file
197
interface/src/DataServerClient.cpp
Normal file
|
@ -0,0 +1,197 @@
|
|||
//
|
||||
// DataServerClient.cpp
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 10/7/13.
|
||||
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include <QtCore/QUrl>
|
||||
|
||||
#include <NodeList.h>
|
||||
#include <PacketHeaders.h>
|
||||
#include <UDPSocket.h>
|
||||
#include <UUID.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "avatar/Profile.h"
|
||||
|
||||
#include "DataServerClient.h"
|
||||
|
||||
|
||||
std::map<unsigned char*, int> DataServerClient::_unmatchedPackets;
|
||||
|
||||
const char DATA_SERVER_HOSTNAME[] = "data.highfidelity.io";
|
||||
const unsigned short DATA_SERVER_PORT = 3282;
|
||||
const sockaddr_in DATA_SERVER_SOCKET = socketForHostnameAndHostOrderPort(DATA_SERVER_HOSTNAME, DATA_SERVER_PORT);
|
||||
|
||||
void DataServerClient::putValueForKey(const char* key, const char* value) {
|
||||
Profile* userProfile = Application::getInstance()->getProfile();
|
||||
QString clientString = userProfile->getUUID().isNull()
|
||||
? userProfile->getUsername()
|
||||
: uuidStringWithoutCurlyBraces(userProfile->getUUID().toString());
|
||||
|
||||
if (!clientString.isEmpty()) {
|
||||
|
||||
unsigned char* putPacket = new unsigned char[MAX_PACKET_SIZE];
|
||||
|
||||
// setup the header for this packet
|
||||
int numPacketBytes = populateTypeAndVersion(putPacket, PACKET_TYPE_DATA_SERVER_PUT);
|
||||
|
||||
// pack the client UUID, null terminated
|
||||
memcpy(putPacket + numPacketBytes, clientString.toLocal8Bit().constData(), clientString.toLocal8Bit().size());
|
||||
numPacketBytes += clientString.toLocal8Bit().size();
|
||||
putPacket[numPacketBytes++] = '\0';
|
||||
|
||||
// pack the key, null terminated
|
||||
strcpy((char*) putPacket + numPacketBytes, key);
|
||||
numPacketBytes += strlen(key);
|
||||
putPacket[numPacketBytes++] = '\0';
|
||||
|
||||
// pack the value, null terminated
|
||||
strcpy((char*) putPacket + numPacketBytes, value);
|
||||
numPacketBytes += strlen(value);
|
||||
putPacket[numPacketBytes++] = '\0';
|
||||
|
||||
// add the putPacket to our vector of unconfirmed packets, will be deleted once put is confirmed
|
||||
_unmatchedPackets.insert(std::pair<unsigned char*, int>(putPacket, numPacketBytes));
|
||||
|
||||
// send this put request to the data server
|
||||
NodeList::getInstance()->getNodeSocket()->send((sockaddr*) &DATA_SERVER_SOCKET, putPacket, numPacketBytes);
|
||||
}
|
||||
}
|
||||
|
||||
void DataServerClient::getValueForKeyAndUUID(const char* key, const QUuid &uuid) {
|
||||
if (!uuid.isNull()) {
|
||||
getValueForKeyAndUserString(key, uuidStringWithoutCurlyBraces(uuid));
|
||||
}
|
||||
}
|
||||
|
||||
void DataServerClient::getValueForKeyAndUserString(const char* key, const QString& userString) {
|
||||
unsigned char* getPacket = new unsigned char[MAX_PACKET_SIZE];
|
||||
|
||||
// setup the header for this packet
|
||||
int numPacketBytes = populateTypeAndVersion(getPacket, PACKET_TYPE_DATA_SERVER_GET);
|
||||
|
||||
// pack the user string (could be username or UUID string), null-terminate
|
||||
memcpy(getPacket + numPacketBytes, userString.toLocal8Bit().constData(), userString.toLocal8Bit().size());
|
||||
numPacketBytes += userString.toLocal8Bit().size();
|
||||
getPacket[numPacketBytes++] = '\0';
|
||||
|
||||
// pack the key, null terminated
|
||||
strcpy((char*) getPacket + numPacketBytes, key);
|
||||
int numKeyBytes = strlen(key);
|
||||
|
||||
if (numKeyBytes > 0) {
|
||||
numPacketBytes += numKeyBytes;
|
||||
getPacket[numPacketBytes++] = '\0';
|
||||
}
|
||||
|
||||
// add the getPacket to our vector of uncofirmed packets, will be deleted once we get a response from the nameserver
|
||||
_unmatchedPackets.insert(std::pair<unsigned char*, int>(getPacket, numPacketBytes));
|
||||
|
||||
// send the get to the data server
|
||||
NodeList::getInstance()->getNodeSocket()->send((sockaddr*) &DATA_SERVER_SOCKET, getPacket, numPacketBytes);
|
||||
}
|
||||
|
||||
void DataServerClient::getClientValueForKey(const char* key) {
|
||||
getValueForKeyAndUserString(key, Application::getInstance()->getProfile()->getUsername());
|
||||
}
|
||||
|
||||
void DataServerClient::processConfirmFromDataServer(unsigned char* packetData, int numPacketBytes) {
|
||||
removeMatchedPacketFromMap(packetData, numPacketBytes);
|
||||
}
|
||||
|
||||
void DataServerClient::processSendFromDataServer(unsigned char* packetData, int numPacketBytes) {
|
||||
// pull the user string from the packet so we know who to associate this with
|
||||
int numHeaderBytes = numBytesForPacketHeader(packetData);
|
||||
|
||||
char* userStringPosition = (char*) packetData + numHeaderBytes;
|
||||
|
||||
QString userString(QByteArray(userStringPosition, strlen(userStringPosition)));
|
||||
|
||||
QUuid userUUID(userString);
|
||||
|
||||
char* dataKeyPosition = (char*) packetData + numHeaderBytes + strlen(userStringPosition) + sizeof('\0');
|
||||
char* dataValuePosition = dataKeyPosition + strlen(dataKeyPosition) + sizeof(char);
|
||||
|
||||
QString dataValueString(QByteArray(dataValuePosition,
|
||||
numPacketBytes - ((unsigned char*) dataValuePosition - packetData)));
|
||||
|
||||
if (userUUID.isNull()) {
|
||||
// the user string was a username
|
||||
// for now assume this means that it is for our avatar
|
||||
|
||||
if (strcmp(dataKeyPosition, DataServerKey::FaceMeshURL) == 0) {
|
||||
// pull the user's face mesh and set it on the Avatar instance
|
||||
|
||||
qDebug("Changing user's face model URL to %s\n", dataValueString.toLocal8Bit().constData());
|
||||
Application::getInstance()->getProfile()->setFaceModelURL(QUrl(dataValueString));
|
||||
} else if (strcmp(dataKeyPosition, DataServerKey::UUID) == 0) {
|
||||
// this is the user's UUID - set it on the profile
|
||||
Application::getInstance()->getProfile()->setUUID(dataValueString);
|
||||
}
|
||||
} else {
|
||||
// user string was UUID, find matching avatar and associate data
|
||||
if (strcmp(dataKeyPosition, DataServerKey::FaceMeshURL) == 0) {
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||
if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) {
|
||||
Avatar* avatar = (Avatar *) node->getLinkedData();
|
||||
|
||||
if (avatar->getUUID() == userUUID) {
|
||||
QMetaObject::invokeMethod(&avatar->getHead().getBlendFace(),
|
||||
"setModelURL",
|
||||
Q_ARG(QUrl, QUrl(dataValueString)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// remove the matched packet from our map so it isn't re-sent to the data-server
|
||||
removeMatchedPacketFromMap(packetData, numPacketBytes);
|
||||
}
|
||||
|
||||
void DataServerClient::processMessageFromDataServer(unsigned char* packetData, int numPacketBytes) {
|
||||
switch (packetData[0]) {
|
||||
case PACKET_TYPE_DATA_SERVER_SEND:
|
||||
processSendFromDataServer(packetData, numPacketBytes);
|
||||
break;
|
||||
case PACKET_TYPE_DATA_SERVER_CONFIRM:
|
||||
processConfirmFromDataServer(packetData, numPacketBytes);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DataServerClient::removeMatchedPacketFromMap(unsigned char* packetData, int numPacketBytes) {
|
||||
for (std::map<unsigned char*, int>::iterator mapIterator = _unmatchedPackets.begin();
|
||||
mapIterator != _unmatchedPackets.end();
|
||||
++mapIterator) {
|
||||
if (memcmp(mapIterator->first + sizeof(PACKET_TYPE),
|
||||
packetData + sizeof(PACKET_TYPE),
|
||||
numPacketBytes - sizeof(PACKET_TYPE)) == 0) {
|
||||
|
||||
// this is a match - remove the confirmed packet from the vector and delete associated member
|
||||
// so it isn't sent back out
|
||||
delete[] mapIterator->first;
|
||||
_unmatchedPackets.erase(mapIterator);
|
||||
|
||||
// we've matched the packet - bail out
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DataServerClient::resendUnmatchedPackets() {
|
||||
for (std::map<unsigned char*, int>::iterator mapIterator = _unmatchedPackets.begin();
|
||||
mapIterator != _unmatchedPackets.end();
|
||||
++mapIterator) {
|
||||
// send the unmatched packet to the data server
|
||||
NodeList::getInstance()->getNodeSocket()->send((sockaddr*) &DATA_SERVER_SOCKET,
|
||||
mapIterator->first,
|
||||
mapIterator->second);
|
||||
}
|
||||
}
|
38
interface/src/DataServerClient.h
Normal file
38
interface/src/DataServerClient.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
//
|
||||
// DataServerClient.h
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 10/7/13.
|
||||
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef __hifi__DataServerClient__
|
||||
#define __hifi__DataServerClient__
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <QtCore/QUuid>
|
||||
|
||||
#include "Application.h"
|
||||
|
||||
class DataServerClient {
|
||||
public:
|
||||
static void putValueForKey(const char* key, const char* value);
|
||||
static void getValueForKeyAndUUID(const char* key, const QUuid& uuid);
|
||||
static void getValueForKeyAndUserString(const char* key, const QString& userString);
|
||||
static void getClientValueForKey(const char* key);
|
||||
static void processConfirmFromDataServer(unsigned char* packetData, int numPacketBytes);
|
||||
static void processSendFromDataServer(unsigned char* packetData, int numPacketBytes);
|
||||
static void processMessageFromDataServer(unsigned char* packetData, int numPacketBytes);
|
||||
static void removeMatchedPacketFromMap(unsigned char* packetData, int numPacketBytes);
|
||||
static void resendUnmatchedPackets();
|
||||
private:
|
||||
static std::map<unsigned char*, int> _unmatchedPackets;
|
||||
};
|
||||
|
||||
namespace DataServerKey {
|
||||
const char FaceMeshURL[] = "mesh";
|
||||
const char UUID[] = "uuid";
|
||||
}
|
||||
|
||||
#endif /* defined(__hifi__DataServerClient__) */
|
|
@ -19,8 +19,12 @@
|
|||
#include <QMainWindow>
|
||||
#include <QSlider>
|
||||
#include <QStandardPaths>
|
||||
#include <QUuid>
|
||||
|
||||
#include <UUID.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "DataServerClient.h"
|
||||
#include "PairingHandler.h"
|
||||
#include "Menu.h"
|
||||
#include "Util.h"
|
||||
|
@ -500,6 +504,7 @@ void Menu::loadSettings(QSettings* settings) {
|
|||
settings->endGroup();
|
||||
|
||||
scanMenuBar(&loadAction, settings);
|
||||
Application::getInstance()->getProfile()->loadData(settings);
|
||||
Application::getInstance()->getAvatar()->loadData(settings);
|
||||
Application::getInstance()->getSwatch()->loadData(settings);
|
||||
}
|
||||
|
@ -522,6 +527,7 @@ void Menu::saveSettings(QSettings* settings) {
|
|||
|
||||
scanMenuBar(&saveAction, settings);
|
||||
Application::getInstance()->getAvatar()->saveData(settings);
|
||||
Application::getInstance()->getProfile()->saveData(settings);
|
||||
Application::getInstance()->getSwatch()->saveData(settings);
|
||||
|
||||
// ask the NodeList to save its data
|
||||
|
@ -742,6 +748,7 @@ QLineEdit* lineEditForDomainHostname() {
|
|||
|
||||
void Menu::editPreferences() {
|
||||
Application* applicationInstance = Application::getInstance();
|
||||
|
||||
QDialog dialog(applicationInstance->getGLWidget());
|
||||
dialog.setWindowTitle("Interface Preferences");
|
||||
QBoxLayout* layout = new QBoxLayout(QBoxLayout::TopToBottom);
|
||||
|
@ -750,13 +757,19 @@ void Menu::editPreferences() {
|
|||
QFormLayout* form = new QFormLayout();
|
||||
layout->addLayout(form, 1);
|
||||
|
||||
QString avatarUsername = applicationInstance->getProfile()->getUsername();
|
||||
QLineEdit* avatarUsernameEdit = new QLineEdit(avatarUsername);
|
||||
avatarUsernameEdit->setMinimumWidth(QLINE_MINIMUM_WIDTH);
|
||||
form->addRow("Username:", avatarUsernameEdit);
|
||||
|
||||
QLineEdit* avatarURL = new QLineEdit(applicationInstance->getAvatar()->getVoxels()->getVoxelURL().toString());
|
||||
avatarURL->setMinimumWidth(QLINE_MINIMUM_WIDTH);
|
||||
form->addRow("Avatar URL:", avatarURL);
|
||||
|
||||
QLineEdit* faceURL = new QLineEdit(applicationInstance->getAvatar()->getHead().getBlendFace().getModelURL().toString());
|
||||
faceURL->setMinimumWidth(QLINE_MINIMUM_WIDTH);
|
||||
form->addRow("Face URL:", faceURL);
|
||||
QString faceURLString = applicationInstance->getProfile()->getFaceModelURL().toString();
|
||||
QLineEdit* faceURLEdit = new QLineEdit(faceURLString);
|
||||
faceURLEdit->setMinimumWidth(QLINE_MINIMUM_WIDTH);
|
||||
form->addRow("Face URL:", faceURLEdit);
|
||||
|
||||
QSlider* pupilDilation = new QSlider(Qt::Horizontal);
|
||||
pupilDilation->setValue(applicationInstance->getAvatar()->getHead().getPupilDilation() * pupilDilation->maximum());
|
||||
|
@ -799,13 +812,32 @@ void Menu::editPreferences() {
|
|||
return;
|
||||
}
|
||||
|
||||
QUrl faceModelURL(faceURLEdit->text());
|
||||
|
||||
|
||||
if (avatarUsernameEdit->text() != avatarUsername) {
|
||||
// there has been a username change - set the new UUID on the avatar instance
|
||||
applicationInstance->getProfile()->setUsername(avatarUsernameEdit->text());
|
||||
|
||||
if (faceModelURL.toString() == faceURLString && !avatarUsernameEdit->text().isEmpty()) {
|
||||
// if there was no change to the face model URL then ask the data-server for what it is
|
||||
DataServerClient::getClientValueForKey(DataServerKey::FaceMeshURL);
|
||||
}
|
||||
}
|
||||
|
||||
if (faceModelURL.toString() != faceURLString) {
|
||||
// change the faceModelURL in the profile, it will also update this user's BlendFace
|
||||
applicationInstance->getProfile()->setFaceModelURL(faceModelURL);
|
||||
|
||||
// send the new face mesh URL to the data-server (if we have a client UUID)
|
||||
DataServerClient::putValueForKey(DataServerKey::FaceMeshURL,
|
||||
faceModelURL.toString().toLocal8Bit().constData());
|
||||
}
|
||||
|
||||
QUrl avatarVoxelURL(avatarURL->text());
|
||||
applicationInstance->getAvatar()->getVoxels()->setVoxelURL(avatarVoxelURL);
|
||||
|
||||
QUrl faceModelURL(faceURL->text());
|
||||
applicationInstance->getAvatar()->getHead().getBlendFace().setModelURL(faceModelURL);
|
||||
|
||||
Avatar::sendAvatarURLsMessage(avatarVoxelURL, faceModelURL);
|
||||
Avatar::sendAvatarURLsMessage(avatarVoxelURL);
|
||||
|
||||
applicationInstance->getAvatar()->getHead().setPupilDilation(pupilDilation->value() / (float)pupilDilation->maximum());
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include "Application.h"
|
||||
#include "Avatar.h"
|
||||
#include "DataServerClient.h"
|
||||
#include "Hand.h"
|
||||
#include "Head.h"
|
||||
#include "Physics.h"
|
||||
|
@ -59,7 +60,7 @@ const int NUM_BODY_CONE_SIDES = 9;
|
|||
const float chatMessageScale = 0.0015;
|
||||
const float chatMessageHeight = 0.20;
|
||||
|
||||
void Avatar::sendAvatarURLsMessage(const QUrl& voxelURL, const QUrl& faceURL) {
|
||||
void Avatar::sendAvatarURLsMessage(const QUrl& voxelURL) {
|
||||
uint16_t ownerID = NodeList::getInstance()->getOwnerID();
|
||||
|
||||
if (ownerID == UNKNOWN_NODE_ID) {
|
||||
|
@ -76,7 +77,6 @@ void Avatar::sendAvatarURLsMessage(const QUrl& voxelURL, const QUrl& faceURL) {
|
|||
|
||||
QDataStream out(&message, QIODevice::WriteOnly | QIODevice::Append);
|
||||
out << voxelURL;
|
||||
out << faceURL;
|
||||
|
||||
Application::controlledBroadcastToNodes((unsigned char*)message.data(), message.size(), &NODE_TYPE_AVATAR_MIXER, 1);
|
||||
}
|
||||
|
@ -751,31 +751,6 @@ void Avatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) {
|
|||
_hand.render(lookingInMirror);
|
||||
}
|
||||
|
||||
|
||||
void Avatar::loadData(QSettings* settings) {
|
||||
settings->beginGroup("Avatar");
|
||||
|
||||
// in case settings is corrupt or missing loadSetting() will check for NaN
|
||||
_bodyYaw = loadSetting(settings, "bodyYaw", 0.0f);
|
||||
_bodyPitch = loadSetting(settings, "bodyPitch", 0.0f);
|
||||
_bodyRoll = loadSetting(settings, "bodyRoll", 0.0f);
|
||||
_position.x = loadSetting(settings, "position_x", 0.0f);
|
||||
_position.y = loadSetting(settings, "position_y", 0.0f);
|
||||
_position.z = loadSetting(settings, "position_z", 0.0f);
|
||||
|
||||
_voxels.setVoxelURL(settings->value("voxelURL").toUrl());
|
||||
_head.getBlendFace().setModelURL(settings->value("faceModelURL").toUrl());
|
||||
_head.setPupilDilation(settings->value("pupilDilation", 0.0f).toFloat());
|
||||
|
||||
_leanScale = loadSetting(settings, "leanScale", 0.05f);
|
||||
|
||||
_newScale = loadSetting(settings, "scale", 1.0f);
|
||||
setScale(_scale);
|
||||
Application::getInstance()->getCamera()->setScale(_scale);
|
||||
|
||||
settings->endGroup();
|
||||
}
|
||||
|
||||
void Avatar::getBodyBallTransform(AvatarJointID jointID, glm::vec3& position, glm::quat& rotation) const {
|
||||
position = _bodyBall[jointID].position;
|
||||
rotation = _bodyBall[jointID].rotation;
|
||||
|
@ -805,27 +780,6 @@ int Avatar::parseData(unsigned char* sourceBuffer, int numBytes) {
|
|||
return bytesRead;
|
||||
}
|
||||
|
||||
void Avatar::saveData(QSettings* set) {
|
||||
set->beginGroup("Avatar");
|
||||
|
||||
set->setValue("bodyYaw", _bodyYaw);
|
||||
set->setValue("bodyPitch", _bodyPitch);
|
||||
set->setValue("bodyRoll", _bodyRoll);
|
||||
|
||||
set->setValue("position_x", _position.x);
|
||||
set->setValue("position_y", _position.y);
|
||||
set->setValue("position_z", _position.z);
|
||||
|
||||
set->setValue("voxelURL", _voxels.getVoxelURL());
|
||||
set->setValue("faceModelURL", _head.getBlendFace().getModelURL());
|
||||
set->setValue("pupilDilation", _head.getPupilDilation());
|
||||
|
||||
set->setValue("leanScale", _leanScale);
|
||||
set->setValue("scale", _newScale);
|
||||
|
||||
set->endGroup();
|
||||
}
|
||||
|
||||
// render a makeshift cone section that serves as a body part connecting joint spheres
|
||||
void Avatar::renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, float radius1, float radius2) {
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
#include <QSettings>
|
||||
#include <QtCore/QUuid>
|
||||
|
||||
#include <AvatarData.h>
|
||||
|
||||
|
@ -129,7 +129,7 @@ class Avatar : public AvatarData {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static void sendAvatarURLsMessage(const QUrl& voxelURL, const QUrl& faceURL);
|
||||
static void sendAvatarURLsMessage(const QUrl& voxelURL);
|
||||
|
||||
Avatar(Node* owningNode = NULL);
|
||||
~Avatar();
|
||||
|
@ -155,10 +155,6 @@ public:
|
|||
glm::quat getOrientation() const;
|
||||
glm::quat getWorldAlignedOrientation() const;
|
||||
AvatarVoxelSystem* getVoxels() { return &_voxels; }
|
||||
|
||||
// get/set avatar data
|
||||
void saveData(QSettings* set);
|
||||
void loadData(QSettings* set);
|
||||
|
||||
// Get the position/rotation of a single body ball
|
||||
void getBodyBallTransform(AvatarJointID jointID, glm::vec3& position, glm::quat& rotation) const;
|
||||
|
@ -247,6 +243,7 @@ private:
|
|||
float _maxArmLength;
|
||||
float _pelvisStandingHeight;
|
||||
|
||||
|
||||
// private methods...
|
||||
glm::vec3 calculateAverageEyePosition() { return _head.calculateAverageEyePosition(); } // get the position smack-dab between the eyes (for lookat)
|
||||
float getBallRenderAlpha(int ball, bool lookingInMirror) const;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <SharedUtil.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "DataServerClient.h"
|
||||
#include "MyAvatar.h"
|
||||
#include "Physics.h"
|
||||
#include "devices/OculusManager.h"
|
||||
|
@ -524,6 +525,50 @@ void MyAvatar::renderScreenTint(ScreenTintLayer layer, Camera& whichCamera) {
|
|||
}
|
||||
}
|
||||
|
||||
void MyAvatar::saveData(QSettings* settings) {
|
||||
settings->beginGroup("Avatar");
|
||||
|
||||
settings->setValue("bodyYaw", _bodyYaw);
|
||||
settings->setValue("bodyPitch", _bodyPitch);
|
||||
settings->setValue("bodyRoll", _bodyRoll);
|
||||
|
||||
settings->setValue("position_x", _position.x);
|
||||
settings->setValue("position_y", _position.y);
|
||||
settings->setValue("position_z", _position.z);
|
||||
|
||||
settings->setValue("voxelURL", _voxels.getVoxelURL());
|
||||
settings->setValue("pupilDilation", _head.getPupilDilation());
|
||||
|
||||
settings->setValue("leanScale", _leanScale);
|
||||
settings->setValue("scale", _newScale);
|
||||
|
||||
settings->endGroup();
|
||||
}
|
||||
|
||||
void MyAvatar::loadData(QSettings* settings) {
|
||||
settings->beginGroup("Avatar");
|
||||
|
||||
// in case settings is corrupt or missing loadSetting() will check for NaN
|
||||
_bodyYaw = loadSetting(settings, "bodyYaw", 0.0f);
|
||||
_bodyPitch = loadSetting(settings, "bodyPitch", 0.0f);
|
||||
_bodyRoll = loadSetting(settings, "bodyRoll", 0.0f);
|
||||
_position.x = loadSetting(settings, "position_x", 0.0f);
|
||||
_position.y = loadSetting(settings, "position_y", 0.0f);
|
||||
_position.z = loadSetting(settings, "position_z", 0.0f);
|
||||
|
||||
_voxels.setVoxelURL(settings->value("voxelURL").toUrl());
|
||||
_head.setPupilDilation(settings->value("pupilDilation", 0.0f).toFloat());
|
||||
|
||||
_leanScale = loadSetting(settings, "leanScale", 0.05f);
|
||||
|
||||
_newScale = loadSetting(settings, "scale", 1.0f);
|
||||
setScale(_scale);
|
||||
Application::getInstance()->getCamera()->setScale(_scale);
|
||||
|
||||
settings->endGroup();
|
||||
}
|
||||
|
||||
|
||||
float MyAvatar::getAbsoluteHeadYaw() const {
|
||||
return glm::yaw(_head.getOrientation());
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#ifndef __interface__myavatar__
|
||||
#define __interface__myavatar__
|
||||
|
||||
#include <QSettings>
|
||||
|
||||
#include "Avatar.h"
|
||||
|
||||
class MyAvatar : public Avatar {
|
||||
|
@ -47,6 +49,10 @@ public:
|
|||
glm::vec3 getGravity() const { return _gravity; }
|
||||
glm::vec3 getUprightHeadPosition() const;
|
||||
glm::vec3 getUprightEyeLevelPosition() const;
|
||||
|
||||
// get/set avatar data
|
||||
void saveData(QSettings* settings);
|
||||
void loadData(QSettings* settings);
|
||||
|
||||
// Set what driving keys are being pressed to control thrust levels
|
||||
void setDriveKeys(int key, bool val) { _driveKeys[key] = val; };
|
||||
|
@ -57,7 +63,7 @@ public:
|
|||
void addThrust(glm::vec3 newThrust) { _thrust += newThrust; };
|
||||
glm::vec3 getThrust() { return _thrust; };
|
||||
|
||||
private:
|
||||
private:
|
||||
bool _mousePressed;
|
||||
float _bodyPitchDelta;
|
||||
float _bodyRollDelta;
|
||||
|
|
71
interface/src/avatar/Profile.cpp
Normal file
71
interface/src/avatar/Profile.cpp
Normal file
|
@ -0,0 +1,71 @@
|
|||
//
|
||||
// Profile.cpp
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 10/8/13.
|
||||
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include <QtCore/QSettings>
|
||||
|
||||
#include "Profile.h"
|
||||
#include "DataServerClient.h"
|
||||
|
||||
Profile::Profile() :
|
||||
_username(),
|
||||
_uuid(),
|
||||
_faceModelURL()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Profile::clear() {
|
||||
_username.clear();
|
||||
_uuid = QUuid();
|
||||
_faceModelURL.clear();
|
||||
}
|
||||
|
||||
void Profile::setUsername(const QString &username) {
|
||||
this->clear();
|
||||
_username = username;
|
||||
|
||||
if (!_username.isEmpty()) {
|
||||
// we've been given a new username, ask the data-server for our UUID
|
||||
DataServerClient::getClientValueForKey(DataServerKey::UUID);
|
||||
}
|
||||
}
|
||||
|
||||
void Profile::setUUID(const QUuid& uuid) {
|
||||
_uuid = uuid;
|
||||
|
||||
// when the UUID is changed we need set it appropriately on our avatar instance
|
||||
Application::getInstance()->getAvatar()->setUUID(_uuid);
|
||||
}
|
||||
|
||||
void Profile::setFaceModelURL(const QUrl& faceModelURL) {
|
||||
_faceModelURL = faceModelURL;
|
||||
|
||||
QMetaObject::invokeMethod(&Application::getInstance()->getAvatar()->getHead().getBlendFace(),
|
||||
"setModelURL",
|
||||
Q_ARG(QUrl, _faceModelURL));
|
||||
}
|
||||
|
||||
void Profile::saveData(QSettings* settings) {
|
||||
settings->beginGroup("Profile");
|
||||
|
||||
settings->setValue("username", _username);
|
||||
settings->setValue("UUID", _uuid);
|
||||
settings->setValue("faceModelURL", _faceModelURL);
|
||||
|
||||
settings->endGroup();
|
||||
}
|
||||
|
||||
void Profile::loadData(QSettings* settings) {
|
||||
settings->beginGroup("Profile");
|
||||
|
||||
_username = settings->value("username").toString();
|
||||
this->setUUID(settings->value("UUID").toUuid());
|
||||
_faceModelURL = settings->value("faceModelURL").toUrl();
|
||||
|
||||
settings->endGroup();
|
||||
}
|
39
interface/src/avatar/Profile.h
Normal file
39
interface/src/avatar/Profile.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
//
|
||||
// Profile.h
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 10/8/13.
|
||||
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef __hifi__Profile__
|
||||
#define __hifi__Profile__
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QUrl>
|
||||
#include <QtCore/QUuid>
|
||||
|
||||
class Profile {
|
||||
public:
|
||||
Profile();
|
||||
|
||||
void setUsername(const QString& username);
|
||||
QString& getUsername() { return _username; }
|
||||
|
||||
void setUUID(const QUuid& uuid);
|
||||
QUuid& getUUID() { return _uuid; }
|
||||
|
||||
void setFaceModelURL(const QUrl& faceModelURL);
|
||||
QUrl& getFaceModelURL() { return _faceModelURL; }
|
||||
|
||||
void clear();
|
||||
|
||||
void saveData(QSettings* settings);
|
||||
void loadData(QSettings* settings);
|
||||
private:
|
||||
QString _username;
|
||||
QUuid _uuid;
|
||||
QUrl _faceModelURL;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__Profile__) */
|
|
@ -23,6 +23,7 @@ static const float fingerVectorRadix = 4; // bits of precision when converting f
|
|||
|
||||
AvatarData::AvatarData(Node* owningNode) :
|
||||
NodeData(owningNode),
|
||||
_uuid(),
|
||||
_handPosition(0,0,0),
|
||||
_bodyYaw(-90.0),
|
||||
_bodyPitch(0.0),
|
||||
|
@ -116,6 +117,11 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
|||
_handData = new HandData(this);
|
||||
}
|
||||
|
||||
// UUID
|
||||
QByteArray uuidByteArray = _uuid.toRfc4122();
|
||||
memcpy(destinationBuffer, uuidByteArray.constData(), uuidByteArray.size());
|
||||
destinationBuffer += uuidByteArray.size();
|
||||
|
||||
// Body world position
|
||||
memcpy(destinationBuffer, &_position, sizeof(float) * 3);
|
||||
destinationBuffer += sizeof(float) * 3;
|
||||
|
@ -249,6 +255,11 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
|||
// push past the node ID
|
||||
sourceBuffer += sizeof(uint16_t);
|
||||
|
||||
// UUID
|
||||
const int NUM_BYTES_RFC4122_UUID = 16;
|
||||
_uuid = QUuid::fromRfc4122(QByteArray((char*) sourceBuffer, NUM_BYTES_RFC4122_UUID));
|
||||
sourceBuffer += NUM_BYTES_RFC4122_UUID;
|
||||
|
||||
// Body world position
|
||||
memcpy(&_position, sourceBuffer, sizeof(float) * 3);
|
||||
sourceBuffer += sizeof(float) * 3;
|
||||
|
@ -259,7 +270,7 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
|||
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &_bodyRoll);
|
||||
|
||||
// Body scale
|
||||
sourceBuffer += unpackFloatRatioFromTwoByte( sourceBuffer, _newScale);
|
||||
sourceBuffer += unpackFloatRatioFromTwoByte(sourceBuffer, _newScale);
|
||||
|
||||
// Follow mode info
|
||||
memcpy(&_leaderID, sourceBuffer, sizeof(uint16_t));
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QUuid>
|
||||
#include <QtCore/QVariantMap>
|
||||
|
||||
#include <NodeData.h>
|
||||
|
@ -72,6 +73,9 @@ public:
|
|||
int getBroadcastData(unsigned char* destinationBuffer);
|
||||
int parseData(unsigned char* sourceBuffer, int numBytes);
|
||||
|
||||
QUuid& getUUID() { return _uuid; }
|
||||
void setUUID(const QUuid& uuid) { _uuid = uuid; }
|
||||
|
||||
// Body Rotation
|
||||
float getBodyYaw() const { return _bodyYaw; }
|
||||
void setBodyYaw(float bodyYaw) { _bodyYaw = bodyYaw; }
|
||||
|
@ -79,7 +83,6 @@ public:
|
|||
void setBodyPitch(float bodyPitch) { _bodyPitch = bodyPitch; }
|
||||
float getBodyRoll() const { return _bodyRoll; }
|
||||
void setBodyRoll(float bodyRoll) { _bodyRoll = bodyRoll; }
|
||||
|
||||
|
||||
// Hand State
|
||||
void setHandState(char s) { _handState = s; }
|
||||
|
@ -133,6 +136,8 @@ public slots:
|
|||
void setWantOcclusionCulling(bool wantOcclusionCulling) { _wantOcclusionCulling = wantOcclusionCulling; }
|
||||
|
||||
protected:
|
||||
QUuid _uuid;
|
||||
|
||||
glm::vec3 _position;
|
||||
glm::vec3 _handPosition;
|
||||
|
||||
|
|
|
@ -139,10 +139,6 @@ void Assignment::setPayload(const uchar* payload, int numBytes) {
|
|||
memcpy(_payload, payload, _numPayloadBytes);
|
||||
}
|
||||
|
||||
QString Assignment::getUUIDStringWithoutCurlyBraces() const {
|
||||
return _uuid.toString().mid(1, _uuid.toString().length() - 2);
|
||||
}
|
||||
|
||||
int Assignment::packToBuffer(unsigned char* buffer) {
|
||||
int numPackedBytes = 0;
|
||||
|
||||
|
|
|
@ -60,7 +60,6 @@ public:
|
|||
|
||||
void setUUID(const QUuid& uuid) { _uuid = uuid; }
|
||||
const QUuid& getUUID() const { return _uuid; }
|
||||
QString getUUIDStringWithoutCurlyBraces() const;
|
||||
void resetUUID() { _uuid = QUuid::createUuid(); }
|
||||
|
||||
Assignment::Command getCommand() const { return _command; }
|
||||
|
|
|
@ -20,7 +20,7 @@ PACKET_VERSION versionForPacketType(PACKET_TYPE type) {
|
|||
return 1;
|
||||
|
||||
case PACKET_TYPE_HEAD_DATA:
|
||||
return 8;
|
||||
return 9;
|
||||
|
||||
case PACKET_TYPE_AVATAR_URLS:
|
||||
return 1;
|
||||
|
|
|
@ -41,6 +41,10 @@ const PACKET_TYPE PACKET_TYPE_DEPLOY_ASSIGNMENT = 'd';
|
|||
const PACKET_TYPE PACKET_TYPE_VOXEL_STATS = '#';
|
||||
const PACKET_TYPE PACKET_TYPE_VOXEL_JURISDICTION = 'J';
|
||||
const PACKET_TYPE PACKET_TYPE_VOXEL_JURISDICTION_REQUEST = 'j';
|
||||
const PACKET_TYPE PACKET_TYPE_DATA_SERVER_PUT = 'p';
|
||||
const PACKET_TYPE PACKET_TYPE_DATA_SERVER_GET = 'g';
|
||||
const PACKET_TYPE PACKET_TYPE_DATA_SERVER_SEND = 'u';
|
||||
const PACKET_TYPE PACKET_TYPE_DATA_SERVER_CONFIRM = 'c';
|
||||
|
||||
typedef char PACKET_VERSION;
|
||||
|
||||
|
|
14
libraries/shared/src/UUID.cpp
Normal file
14
libraries/shared/src/UUID.cpp
Normal file
|
@ -0,0 +1,14 @@
|
|||
//
|
||||
// UUID.cpp
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 10/7/13.
|
||||
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include "UUID.h"
|
||||
|
||||
QString uuidStringWithoutCurlyBraces(const QUuid& uuid) {
|
||||
QString uuidStringNoBraces = uuid.toString().mid(1, uuid.toString().length() - 2);
|
||||
return uuidStringNoBraces;
|
||||
}
|
16
libraries/shared/src/UUID.h
Normal file
16
libraries/shared/src/UUID.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
//
|
||||
// UUID.h
|
||||
// hifi
|
||||
//
|
||||
// Created by Stephen Birarda on 10/7/13.
|
||||
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef __hifi__UUID__
|
||||
#define __hifi__UUID__
|
||||
|
||||
#include <QtCore/QUuid>
|
||||
|
||||
QString uuidStringWithoutCurlyBraces(const QUuid& uuid);
|
||||
|
||||
#endif /* defined(__hifi__UUID__) */
|
Loading…
Reference in a new issue