mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-04 22:39:45 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into model_browsing
This commit is contained in:
commit
3cd4761fa7
10 changed files with 504 additions and 107 deletions
12
BUILD.md
12
BUILD.md
|
@ -104,9 +104,7 @@ We don't currently have a Windows installer, so before running Interface, you wi
|
|||
|
||||
CMake will need to know where the headers and libraries for required external dependencies are. If you installed ZLIB using the installer, the FindZLIB cmake module will be able to find it. This isn't the case for the others.
|
||||
|
||||
You have the choice of setting a variable specific to each library, or having a folder using a defined structure that contains all of the libs.
|
||||
|
||||
The recommended route is to place all of the dependencies in one place and set one ENV variable - HIFI_LIB_DIR. That ENV variable should point to a directory with the following structure:
|
||||
The recommended route for CMake to find external dependencies is to place all of the dependencies in one folder and set one ENV variable - HIFI_LIB_DIR. That ENV variable should point to a directory with the following structure:
|
||||
|
||||
root_lib_dir
|
||||
-> glm
|
||||
|
@ -128,14 +126,6 @@ The recommended route is to place all of the dependencies in one place and set o
|
|||
|
||||
For many of the external libraries where precompiled binaries are readily available you should be able to simply copy the extracted folder that you get from the download links provided at the top of the guide. Otherwise you may need to build from source and install the built product to this directory. The `root_lib_dir` in the above example can be wherever you choose on your system - as long as the environment variable HIFI_LIB_DIR is set to it.
|
||||
|
||||
Should you want to define a location for each library, these are the associated variables you will want to set:
|
||||
|
||||
`GLM_ROOT_DIR, GLUT_ROOT_DIR, GLEW_ROOT_DIR`
|
||||
|
||||
They can be set in your ENV or by passing them to the cmake command on the command line. (There is an example of this in the CMake section earlier in this guide.)
|
||||
|
||||
Each of those designates the root directory that contains the sub-folders for each library. For example, if the GLEW_ROOT_DIR is `C:\libs\glew`, then we would expect to find an `include` folder and a `lib` folder inside `C:\libs\glew`.
|
||||
|
||||
*NOTE: Qt does not support 64-bit builds on Windows 7, so you must use the 32-bit version of libraries for interface.exe to run. The 32-bit version of the static library is the one linked by our CMake find modules*
|
||||
|
||||
#### DLLs
|
||||
|
|
|
@ -423,17 +423,25 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif
|
|||
QDataStream broadcastDataStream(&broadcastPacket, QIODevice::Append);
|
||||
broadcastDataStream << node->getUUID();
|
||||
|
||||
int numBroadcastPacketLeadBytes = broadcastDataStream.device()->pos();
|
||||
|
||||
DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(node->getLinkedData());
|
||||
|
||||
NodeList* nodeList = NodeList::getInstance();
|
||||
|
||||
|
||||
if (nodeInterestList.size() > 0) {
|
||||
// if the node has any interest types, send back those nodes as well
|
||||
foreach (const SharedNodePointer& otherNode, nodeList->getNodeHash()) {
|
||||
|
||||
// reset our nodeByteArray and nodeDataStream
|
||||
QByteArray nodeByteArray;
|
||||
QDataStream nodeDataStream(&nodeByteArray, QIODevice::Append);
|
||||
|
||||
if (otherNode->getUUID() != node->getUUID() && nodeInterestList.contains(otherNode->getType())) {
|
||||
|
||||
// don't send avatar nodes to other avatars, that will come from avatar mixer
|
||||
broadcastDataStream << *otherNode.data();
|
||||
nodeDataStream << *otherNode.data();
|
||||
|
||||
// pack the secret that these two nodes will use to communicate with each other
|
||||
QUuid secretUUID = nodeData->getSessionSecretHash().value(otherNode->getUUID());
|
||||
|
@ -450,11 +458,26 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif
|
|||
|
||||
}
|
||||
|
||||
broadcastDataStream << secretUUID;
|
||||
nodeDataStream << secretUUID;
|
||||
|
||||
if (broadcastPacket.size() + nodeByteArray.size() > MAX_PACKET_SIZE) {
|
||||
// we need to break here and start a new packet
|
||||
// so send the current one
|
||||
|
||||
nodeList->writeDatagram(broadcastPacket, node, senderSockAddr);
|
||||
|
||||
// reset the broadcastPacket structure
|
||||
broadcastPacket.resize(numBroadcastPacketLeadBytes);
|
||||
broadcastDataStream.device()->seek(numBroadcastPacketLeadBytes);
|
||||
}
|
||||
|
||||
// append the nodeByteArray to the current state of broadcastDataStream
|
||||
broadcastPacket.append(nodeByteArray);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// always write the last broadcastPacket
|
||||
nodeList->writeDatagram(broadcastPacket, node, senderSockAddr);
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ configure_file(InterfaceVersion.h.in "${PROJECT_BINARY_DIR}/includes/InterfaceVe
|
|||
|
||||
# grab the implementation and header files from src dirs
|
||||
file(GLOB INTERFACE_SRCS src/*.cpp src/*.h)
|
||||
foreach(SUBDIR avatar devices renderer ui starfield)
|
||||
foreach(SUBDIR avatar devices renderer ui starfield location)
|
||||
file(GLOB_RECURSE SUBDIR_SRCS src/${SUBDIR}/*.cpp src/${SUBDIR}/*.h)
|
||||
set(INTERFACE_SRCS ${INTERFACE_SRCS} "${SUBDIR_SRCS}")
|
||||
endforeach(SUBDIR)
|
||||
|
|
|
@ -113,18 +113,18 @@
|
|||
<context>
|
||||
<name>Menu</name>
|
||||
<message>
|
||||
<location filename="src/Menu.cpp" line="429"/>
|
||||
<location filename="src/Menu.cpp" line="437"/>
|
||||
<source>Open .ini config file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="src/Menu.cpp" line="431"/>
|
||||
<location filename="src/Menu.cpp" line="443"/>
|
||||
<location filename="src/Menu.cpp" line="439"/>
|
||||
<location filename="src/Menu.cpp" line="451"/>
|
||||
<source>Text files (*.ini)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="src/Menu.cpp" line="441"/>
|
||||
<location filename="src/Menu.cpp" line="449"/>
|
||||
<source>Save .ini config file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <QLineEdit>
|
||||
#include <QMainWindow>
|
||||
#include <QMenuBar>
|
||||
#include <QMessageBox>
|
||||
#include <QShortcut>
|
||||
#include <QSlider>
|
||||
#include <QStandardPaths>
|
||||
|
@ -36,6 +37,7 @@
|
|||
#include "InfoView.h"
|
||||
#include "ui/MetavoxelEditor.h"
|
||||
|
||||
|
||||
Menu* Menu::_instance = NULL;
|
||||
|
||||
Menu* Menu::getInstance() {
|
||||
|
@ -78,7 +80,7 @@ Menu::Menu() :
|
|||
_loginAction(NULL)
|
||||
{
|
||||
Application *appInstance = Application::getInstance();
|
||||
|
||||
|
||||
QMenu* fileMenu = addMenu("File");
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
|
@ -116,13 +118,18 @@ Menu::Menu() :
|
|||
addActionToQMenuAndActionHash(fileMenu,
|
||||
MenuOption::GoToDomain,
|
||||
Qt::CTRL | Qt::Key_D,
|
||||
this,
|
||||
SLOT(goToDomainDialog()));
|
||||
this,
|
||||
SLOT(goToDomainDialog()));
|
||||
addActionToQMenuAndActionHash(fileMenu,
|
||||
MenuOption::GoToLocation,
|
||||
Qt::CTRL | Qt::SHIFT | Qt::Key_L,
|
||||
this,
|
||||
SLOT(goToLocation()));
|
||||
this,
|
||||
SLOT(goToLocation()));
|
||||
addActionToQMenuAndActionHash(fileMenu,
|
||||
MenuOption::NameLocation,
|
||||
Qt::CTRL | Qt::Key_N,
|
||||
this,
|
||||
SLOT(nameLocation()));
|
||||
addActionToQMenuAndActionHash(fileMenu,
|
||||
MenuOption::GoTo,
|
||||
Qt::Key_At,
|
||||
|
@ -421,6 +428,7 @@ void Menu::saveSettings(QSettings* settings) {
|
|||
scanMenuBar(&saveAction, settings);
|
||||
Application::getInstance()->getAvatar()->saveData(settings);
|
||||
NodeList::getInstance()->saveData(settings);
|
||||
|
||||
}
|
||||
|
||||
void Menu::importSettings() {
|
||||
|
@ -864,67 +872,11 @@ void Menu::goToDomainDialog() {
|
|||
}
|
||||
|
||||
void Menu::goToOrientation(QString orientation) {
|
||||
|
||||
if (orientation.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QStringList orientationItems = orientation.split(QRegExp("_|,"), QString::SkipEmptyParts);
|
||||
|
||||
const int NUMBER_OF_ORIENTATION_ITEMS = 4;
|
||||
const int W_ITEM = 0;
|
||||
const int X_ITEM = 1;
|
||||
const int Y_ITEM = 2;
|
||||
const int Z_ITEM = 3;
|
||||
|
||||
if (orientationItems.size() == NUMBER_OF_ORIENTATION_ITEMS) {
|
||||
|
||||
double w = replaceLastOccurrence('-', '.', orientationItems[W_ITEM].trimmed()).toDouble();
|
||||
double x = replaceLastOccurrence('-', '.', orientationItems[X_ITEM].trimmed()).toDouble();
|
||||
double y = replaceLastOccurrence('-', '.', orientationItems[Y_ITEM].trimmed()).toDouble();
|
||||
double z = replaceLastOccurrence('-', '.', orientationItems[Z_ITEM].trimmed()).toDouble();
|
||||
|
||||
glm::quat newAvatarOrientation(w, x, y, z);
|
||||
|
||||
MyAvatar* myAvatar = Application::getInstance()->getAvatar();
|
||||
glm::quat avatarOrientation = myAvatar->getOrientation();
|
||||
if (newAvatarOrientation != avatarOrientation) {
|
||||
myAvatar->setOrientation(newAvatarOrientation);
|
||||
}
|
||||
}
|
||||
LocationManager::getInstance().goToDestination(orientation);
|
||||
}
|
||||
|
||||
bool Menu::goToDestination(QString destination) {
|
||||
|
||||
QStringList coordinateItems = destination.split(QRegExp("_|,"), QString::SkipEmptyParts);
|
||||
|
||||
const int NUMBER_OF_COORDINATE_ITEMS = 3;
|
||||
const int X_ITEM = 0;
|
||||
const int Y_ITEM = 1;
|
||||
const int Z_ITEM = 2;
|
||||
if (coordinateItems.size() == NUMBER_OF_COORDINATE_ITEMS) {
|
||||
|
||||
double x = replaceLastOccurrence('-', '.', coordinateItems[X_ITEM].trimmed()).toDouble();
|
||||
double y = replaceLastOccurrence('-', '.', coordinateItems[Y_ITEM].trimmed()).toDouble();
|
||||
double z = replaceLastOccurrence('-', '.', coordinateItems[Z_ITEM].trimmed()).toDouble();
|
||||
|
||||
glm::vec3 newAvatarPos(x, y, z);
|
||||
|
||||
MyAvatar* myAvatar = Application::getInstance()->getAvatar();
|
||||
glm::vec3 avatarPos = myAvatar->getPosition();
|
||||
if (newAvatarPos != avatarPos) {
|
||||
// send a node kill request, indicating to other clients that they should play the "disappeared" effect
|
||||
MyAvatar::sendKillAvatar();
|
||||
|
||||
qDebug("Going To Location: %f, %f, %f...", x, y, z);
|
||||
myAvatar->setPosition(newAvatarPos);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// no coordinates were parsed
|
||||
return false;
|
||||
return LocationManager::getInstance().goToDestination(destination);
|
||||
}
|
||||
|
||||
void Menu::goTo() {
|
||||
|
@ -939,25 +891,33 @@ void Menu::goTo() {
|
|||
|
||||
int dialogReturn = gotoDialog.exec();
|
||||
if (dialogReturn == QDialog::Accepted && !gotoDialog.textValue().isEmpty()) {
|
||||
|
||||
destination = gotoDialog.textValue();
|
||||
|
||||
// go to coordinate destination or to Username
|
||||
if (!goToDestination(destination)) {
|
||||
JSONCallbackParameters callbackParams;
|
||||
callbackParams.jsonCallbackReceiver = Application::getInstance()->getAvatar();
|
||||
callbackParams.jsonCallbackMethod = "goToLocationFromResponse";
|
||||
|
||||
// there's a username entered by the user, make a request to the data-server for the associated location
|
||||
AccountManager::getInstance().authenticatedRequest("/api/v1/users/" + gotoDialog.textValue() + "/address",
|
||||
QNetworkAccessManager::GetOperation,
|
||||
callbackParams);
|
||||
}
|
||||
LocationManager* manager = &LocationManager::getInstance();
|
||||
manager->goTo(gotoDialog.textValue());
|
||||
connect(manager, &LocationManager::multipleDestinationsFound, this, &Menu::multipleDestinationsDecision);
|
||||
}
|
||||
|
||||
sendFakeEnterEvent();
|
||||
}
|
||||
|
||||
void Menu::multipleDestinationsDecision(const QJsonObject& userData, const QJsonObject& placeData) {
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText("Both user and location exists with same name");
|
||||
msgBox.setInformativeText("Where you wanna go?");
|
||||
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Open);
|
||||
msgBox.button(QMessageBox::Ok)->setText("User");
|
||||
msgBox.button(QMessageBox::Open)->setText("Place");
|
||||
int userResponse = msgBox.exec();
|
||||
|
||||
if (userResponse == QMessageBox::Ok) {
|
||||
Application::getInstance()->getAvatar()->goToLocationFromResponse(userData);
|
||||
} else if (userResponse == QMessageBox::Open) {
|
||||
Application::getInstance()->getAvatar()->goToLocationFromResponse(userData);
|
||||
}
|
||||
|
||||
LocationManager* manager = reinterpret_cast<LocationManager*>(sender());
|
||||
disconnect(manager, &LocationManager::multipleDestinationsFound, this, &Menu::multipleDestinationsDecision);
|
||||
}
|
||||
|
||||
void Menu::goToLocation() {
|
||||
MyAvatar* myAvatar = Application::getInstance()->getAvatar();
|
||||
glm::vec3 avatarPos = myAvatar->getPosition();
|
||||
|
@ -980,6 +940,69 @@ void Menu::goToLocation() {
|
|||
sendFakeEnterEvent();
|
||||
}
|
||||
|
||||
void Menu::namedLocationCreated(LocationManager::NamedLocationCreateResponse response) {
|
||||
|
||||
if (response == LocationManager::Created) {
|
||||
return;
|
||||
}
|
||||
|
||||
QMessageBox msgBox;
|
||||
switch (response) {
|
||||
case LocationManager::AlreadyExists:
|
||||
msgBox.setText("That name has been already claimed, try something else.");
|
||||
break;
|
||||
default:
|
||||
msgBox.setText("An unexpected error has occurred, please try again later.");
|
||||
break;
|
||||
}
|
||||
|
||||
msgBox.exec();
|
||||
}
|
||||
|
||||
void Menu::nameLocation() {
|
||||
// check if user is logged in or show login dialog if not
|
||||
|
||||
AccountManager& accountManager = AccountManager::getInstance();
|
||||
if (!accountManager.isLoggedIn()) {
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText("We need to tie this location to your username.");
|
||||
msgBox.setInformativeText("Please login first, then try naming the location again.");
|
||||
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
|
||||
msgBox.button(QMessageBox::Ok)->setText("Login");
|
||||
if (msgBox.exec() == QMessageBox::Ok) {
|
||||
loginForCurrentDomain();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
QInputDialog nameDialog(Application::getInstance()->getWindow());
|
||||
nameDialog.setWindowTitle("Name this location");
|
||||
nameDialog.setLabelText("Name this location, then share that name with others.\n"
|
||||
"When they come here, they'll be in the same location and orientation\n"
|
||||
"(wherever you are standing and looking now) as you.\n\n"
|
||||
"Location name:");
|
||||
|
||||
nameDialog.setWindowFlags(Qt::Sheet);
|
||||
nameDialog.resize((int) (nameDialog.parentWidget()->size().width() * 0.30), nameDialog.size().height());
|
||||
|
||||
if (nameDialog.exec() == QDialog::Accepted) {
|
||||
|
||||
QString locationName = nameDialog.textValue().trimmed();
|
||||
if (locationName.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
MyAvatar* myAvatar = Application::getInstance()->getAvatar();
|
||||
LocationManager* manager = new LocationManager();
|
||||
connect(manager, &LocationManager::creationCompleted, this, &Menu::namedLocationCreated);
|
||||
NamedLocation* location = new NamedLocation(locationName,
|
||||
myAvatar->getPosition(), myAvatar->getOrientation(),
|
||||
NodeList::getInstance()->getDomainInfo().getHostname());
|
||||
manager->createNamedLocation(location);
|
||||
}
|
||||
}
|
||||
|
||||
void Menu::pasteToVoxel() {
|
||||
QInputDialog pasteToOctalCodeDialog(Application::getInstance()->getWindow());
|
||||
pasteToOctalCodeDialog.setWindowTitle("Paste to Voxel");
|
||||
|
@ -1246,17 +1269,6 @@ void Menu::addAvatarCollisionSubMenu(QMenu* overMenu) {
|
|||
0, true, avatar, SLOT(updateCollisionFlags()));
|
||||
}
|
||||
|
||||
QString Menu::replaceLastOccurrence(QChar search, QChar replace, QString string) {
|
||||
int lastIndex;
|
||||
lastIndex = string.lastIndexOf(search);
|
||||
if (lastIndex > 0) {
|
||||
lastIndex = string.lastIndexOf(search);
|
||||
string.replace(lastIndex, 1, replace);
|
||||
}
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
QAction* Menu::getActionFromName(const QString& menuName, QMenu* menu) {
|
||||
QList<QAction*> menuActions;
|
||||
if (menu) {
|
||||
|
|
|
@ -18,7 +18,8 @@
|
|||
#include <MenuItemProperties.h>
|
||||
#include <OctreeConstants.h>
|
||||
|
||||
#include <ui/ChatWindow.h>
|
||||
#include "location/LocationManager.h"
|
||||
#include "ui/ChatWindow.h"
|
||||
|
||||
const float ADJUST_LOD_DOWN_FPS = 40.0;
|
||||
const float ADJUST_LOD_UP_FPS = 55.0;
|
||||
|
@ -138,6 +139,7 @@ private slots:
|
|||
void editPreferences();
|
||||
void goToDomainDialog();
|
||||
void goToLocation();
|
||||
void nameLocation();
|
||||
void bandwidthDetailsClosed();
|
||||
void octreeStatsDetailsClosed();
|
||||
void lodToolsClosed();
|
||||
|
@ -147,6 +149,8 @@ private slots:
|
|||
void showChat();
|
||||
void toggleChat();
|
||||
void audioMuteToggled();
|
||||
void namedLocationCreated(LocationManager::NamedLocationCreateResponse response);
|
||||
void multipleDestinationsDecision(const QJsonObject& userData, const QJsonObject& placeData);
|
||||
|
||||
private:
|
||||
static Menu* _instance;
|
||||
|
@ -248,6 +252,7 @@ namespace MenuOption {
|
|||
const QString GlowMode = "Cycle Glow Mode";
|
||||
const QString GoToDomain = "Go To Domain...";
|
||||
const QString GoToLocation = "Go To Location...";
|
||||
const QString NameLocation = "Name this location";
|
||||
const QString GoTo = "Go To...";
|
||||
const QString IncreaseAvatarSize = "Increase Avatar Size";
|
||||
const QString IncreaseVoxelSize = "Increase Voxel Size";
|
||||
|
|
227
interface/src/location/LocationManager.cpp
Normal file
227
interface/src/location/LocationManager.cpp
Normal file
|
@ -0,0 +1,227 @@
|
|||
//
|
||||
// LocationManager.cpp
|
||||
// hifi
|
||||
//
|
||||
// Created by Stojce Slavkovski on 2/7/14.
|
||||
//
|
||||
//
|
||||
|
||||
#include "Application.h"
|
||||
#include "LocationManager.h"
|
||||
|
||||
const QString GET_USER_ADDRESS = "/api/v1/users/%1/address";
|
||||
const QString GET_PLACE_ADDRESS = "/api/v1/places/%1/address";
|
||||
const QString POST_PLACE_CREATE = "/api/v1/places/";
|
||||
|
||||
|
||||
LocationManager::LocationManager() : _userData(), _placeData() {
|
||||
|
||||
};
|
||||
|
||||
LocationManager& LocationManager::getInstance() {
|
||||
static LocationManager sharedInstance;
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
void LocationManager::namedLocationDataReceived(const QJsonObject& data) {
|
||||
if (data.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (data.contains("status") && data["status"].toString() == "success") {
|
||||
emit creationCompleted(LocationManager::Created);
|
||||
} else {
|
||||
emit creationCompleted(LocationManager::AlreadyExists);
|
||||
}
|
||||
}
|
||||
|
||||
void LocationManager::errorDataReceived(QNetworkReply::NetworkError error, const QString& message) {
|
||||
emit creationCompleted(LocationManager::SystemError);
|
||||
}
|
||||
|
||||
void LocationManager::createNamedLocation(NamedLocation* namedLocation) {
|
||||
AccountManager& accountManager = AccountManager::getInstance();
|
||||
if (accountManager.isLoggedIn()) {
|
||||
JSONCallbackParameters callbackParams;
|
||||
callbackParams.jsonCallbackReceiver = this;
|
||||
callbackParams.jsonCallbackMethod = "namedLocationDataReceived";
|
||||
callbackParams.errorCallbackReceiver = this;
|
||||
callbackParams.errorCallbackMethod = "errorDataReceived";
|
||||
|
||||
accountManager.authenticatedRequest(POST_PLACE_CREATE, QNetworkAccessManager::PostOperation,
|
||||
callbackParams, namedLocation->toJsonString().toUtf8());
|
||||
}
|
||||
}
|
||||
|
||||
void LocationManager::goTo(QString destination) {
|
||||
|
||||
if (destination.startsWith("@")) {
|
||||
// remove '@' and go to user
|
||||
goToUser(destination.remove(0, 1));
|
||||
return;
|
||||
}
|
||||
|
||||
if (destination.startsWith("#")) {
|
||||
// remove '#' and go to named place
|
||||
goToPlace(destination.remove(0, 1));
|
||||
return;
|
||||
}
|
||||
|
||||
// go to coordinate destination or to Username
|
||||
if (!goToDestination(destination)) {
|
||||
// reset data on local variables
|
||||
_userData = QJsonObject();
|
||||
_placeData = QJsonObject();
|
||||
|
||||
destination = QString(QUrl::toPercentEncoding(destination));
|
||||
JSONCallbackParameters callbackParams;
|
||||
callbackParams.jsonCallbackReceiver = this;
|
||||
callbackParams.jsonCallbackMethod = "goToUserFromResponse";
|
||||
AccountManager::getInstance().authenticatedRequest(GET_USER_ADDRESS.arg(destination),
|
||||
QNetworkAccessManager::GetOperation,
|
||||
callbackParams);
|
||||
|
||||
callbackParams.jsonCallbackMethod = "goToLocationFromResponse";
|
||||
AccountManager::getInstance().authenticatedRequest(GET_PLACE_ADDRESS.arg(destination),
|
||||
QNetworkAccessManager::GetOperation,
|
||||
callbackParams);
|
||||
}
|
||||
}
|
||||
|
||||
void LocationManager::goToUserFromResponse(const QJsonObject& jsonObject) {
|
||||
_userData = jsonObject;
|
||||
checkForMultipleDestinations();
|
||||
}
|
||||
|
||||
void LocationManager::goToLocationFromResponse(const QJsonObject& jsonObject) {
|
||||
_placeData = jsonObject;
|
||||
checkForMultipleDestinations();
|
||||
}
|
||||
|
||||
void LocationManager::checkForMultipleDestinations() {
|
||||
if (!_userData.isEmpty() && !_placeData.isEmpty()) {
|
||||
if (_userData.contains("status") && _userData["status"].toString() == "success" &&
|
||||
_placeData.contains("status") && _placeData["status"].toString() == "success") {
|
||||
emit multipleDestinationsFound(_userData, _placeData);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_userData.contains("status") && _userData["status"].toString() == "success") {
|
||||
Application::getInstance()->getAvatar()->goToLocationFromResponse(_userData);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_placeData.contains("status") && _placeData["status"].toString() == "success") {
|
||||
Application::getInstance()->getAvatar()->goToLocationFromResponse(_placeData);
|
||||
return;
|
||||
}
|
||||
|
||||
emit locationChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void LocationManager::goToUser(QString userName) {
|
||||
|
||||
JSONCallbackParameters callbackParams;
|
||||
callbackParams.jsonCallbackReceiver = Application::getInstance()->getAvatar();
|
||||
callbackParams.jsonCallbackMethod = "goToLocationFromResponse";
|
||||
|
||||
userName = QString(QUrl::toPercentEncoding(userName));
|
||||
AccountManager::getInstance().authenticatedRequest(GET_USER_ADDRESS.arg(userName),
|
||||
QNetworkAccessManager::GetOperation,
|
||||
callbackParams);
|
||||
}
|
||||
|
||||
void LocationManager::goToPlace(QString placeName) {
|
||||
JSONCallbackParameters callbackParams;
|
||||
callbackParams.jsonCallbackReceiver = Application::getInstance()->getAvatar();
|
||||
callbackParams.jsonCallbackMethod = "goToLocationFromResponse";
|
||||
|
||||
placeName = QString(QUrl::toPercentEncoding(placeName));
|
||||
AccountManager::getInstance().authenticatedRequest(GET_PLACE_ADDRESS.arg(placeName),
|
||||
QNetworkAccessManager::GetOperation,
|
||||
callbackParams);
|
||||
}
|
||||
|
||||
void LocationManager::goToOrientation(QString orientation) {
|
||||
if (orientation.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QStringList orientationItems = orientation.remove(' ').split(QRegExp("_|,"), QString::SkipEmptyParts);
|
||||
|
||||
const int NUMBER_OF_ORIENTATION_ITEMS = 4;
|
||||
const int W_ITEM = 0;
|
||||
const int X_ITEM = 1;
|
||||
const int Y_ITEM = 2;
|
||||
const int Z_ITEM = 3;
|
||||
|
||||
if (orientationItems.size() == NUMBER_OF_ORIENTATION_ITEMS) {
|
||||
|
||||
// replace last occurrence of '_' with decimal point
|
||||
replaceLastOccurrence('-', '.', orientationItems[W_ITEM]);
|
||||
replaceLastOccurrence('-', '.', orientationItems[X_ITEM]);
|
||||
replaceLastOccurrence('-', '.', orientationItems[Y_ITEM]);
|
||||
replaceLastOccurrence('-', '.', orientationItems[Z_ITEM]);
|
||||
|
||||
double w = orientationItems[W_ITEM].toDouble();
|
||||
double x = orientationItems[X_ITEM].toDouble();
|
||||
double y = orientationItems[Y_ITEM].toDouble();
|
||||
double z = orientationItems[Z_ITEM].toDouble();
|
||||
|
||||
glm::quat newAvatarOrientation(w, x, y, z);
|
||||
|
||||
MyAvatar* myAvatar = Application::getInstance()->getAvatar();
|
||||
glm::quat avatarOrientation = myAvatar->getOrientation();
|
||||
if (newAvatarOrientation != avatarOrientation) {
|
||||
myAvatar->setOrientation(newAvatarOrientation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LocationManager::goToDestination(QString destination) {
|
||||
|
||||
QStringList coordinateItems = destination.remove(' ').split(QRegExp("_|,"), QString::SkipEmptyParts);
|
||||
|
||||
const int NUMBER_OF_COORDINATE_ITEMS = 3;
|
||||
const int X_ITEM = 0;
|
||||
const int Y_ITEM = 1;
|
||||
const int Z_ITEM = 2;
|
||||
if (coordinateItems.size() == NUMBER_OF_COORDINATE_ITEMS) {
|
||||
|
||||
// replace last occurrence of '_' with decimal point
|
||||
replaceLastOccurrence('-', '.', coordinateItems[X_ITEM]);
|
||||
replaceLastOccurrence('-', '.', coordinateItems[Y_ITEM]);
|
||||
replaceLastOccurrence('-', '.', coordinateItems[Z_ITEM]);
|
||||
|
||||
double x = coordinateItems[X_ITEM].toDouble();
|
||||
double y = coordinateItems[Y_ITEM].toDouble();
|
||||
double z = coordinateItems[Z_ITEM].toDouble();
|
||||
|
||||
glm::vec3 newAvatarPos(x, y, z);
|
||||
|
||||
MyAvatar* myAvatar = Application::getInstance()->getAvatar();
|
||||
glm::vec3 avatarPos = myAvatar->getPosition();
|
||||
if (newAvatarPos != avatarPos) {
|
||||
// send a node kill request, indicating to other clients that they should play the "disappeared" effect
|
||||
MyAvatar::sendKillAvatar();
|
||||
|
||||
qDebug("Going To Location: %f, %f, %f...", x, y, z);
|
||||
myAvatar->setPosition(newAvatarPos);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// no coordinates were parsed
|
||||
return false;
|
||||
}
|
||||
|
||||
void LocationManager::replaceLastOccurrence(const QChar search, const QChar replace, QString& string) {
|
||||
int lastIndex;
|
||||
lastIndex = string.lastIndexOf(search);
|
||||
if (lastIndex > 0) {
|
||||
lastIndex = string.lastIndexOf(search);
|
||||
string.replace(lastIndex, 1, replace);
|
||||
}
|
||||
}
|
58
interface/src/location/LocationManager.h
Normal file
58
interface/src/location/LocationManager.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
//
|
||||
// LocationManager.h
|
||||
// hifi
|
||||
//
|
||||
// Created by Stojce Slavkovski on 2/7/14.
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef __hifi__LocationManager__
|
||||
#define __hifi__LocationManager__
|
||||
|
||||
#include <QtCore>
|
||||
|
||||
#include "AccountManager.h"
|
||||
#include "NamedLocation.h"
|
||||
|
||||
class LocationManager : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static LocationManager& getInstance();
|
||||
|
||||
enum NamedLocationCreateResponse {
|
||||
Created,
|
||||
AlreadyExists,
|
||||
SystemError
|
||||
};
|
||||
|
||||
LocationManager();
|
||||
void createNamedLocation(NamedLocation* namedLocation);
|
||||
|
||||
void goTo(QString destination);
|
||||
void goToUser(QString userName);
|
||||
void goToPlace(QString placeName);
|
||||
void goToOrientation(QString orientation);
|
||||
bool goToDestination(QString destination);
|
||||
|
||||
private:
|
||||
QJsonObject _userData;
|
||||
QJsonObject _placeData;
|
||||
|
||||
void replaceLastOccurrence(const QChar search, const QChar replace, QString& string);
|
||||
void checkForMultipleDestinations();
|
||||
|
||||
signals:
|
||||
void creationCompleted(LocationManager::NamedLocationCreateResponse response);
|
||||
void multipleDestinationsFound(const QJsonObject& userData, const QJsonObject& placeData);
|
||||
void locationChanged();
|
||||
|
||||
private slots:
|
||||
void namedLocationDataReceived(const QJsonObject& data);
|
||||
void errorDataReceived(QNetworkReply::NetworkError error, const QString& message);
|
||||
void goToLocationFromResponse(const QJsonObject& jsonObject);
|
||||
void goToUserFromResponse(const QJsonObject& jsonObject);
|
||||
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__LocationManager__) */
|
24
interface/src/location/NamedLocation.cpp
Normal file
24
interface/src/location/NamedLocation.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
//
|
||||
// LocationManager.cpp
|
||||
// hifi
|
||||
//
|
||||
// Created by Stojce Slavkovski on 2/1/14.
|
||||
//
|
||||
//
|
||||
|
||||
#include "NamedLocation.h"
|
||||
|
||||
const QString JSON_FORMAT = "{\"address\":{\"position\":\"%1,%2,%3\","
|
||||
"\"orientation\":\"%4,%5,%6,%7\",\"domain\":\"%8\"},\"name\":\"%9\"}";
|
||||
|
||||
QString NamedLocation::toJsonString() {
|
||||
return JSON_FORMAT.arg(QString::number(_location.x),
|
||||
QString::number(_location.y),
|
||||
QString::number(_location.z),
|
||||
QString::number(_orientation.w),
|
||||
QString::number(_orientation.x),
|
||||
QString::number(_orientation.y),
|
||||
QString::number(_orientation.z),
|
||||
_domain,
|
||||
_locationName);
|
||||
}
|
58
interface/src/location/NamedLocation.h
Normal file
58
interface/src/location/NamedLocation.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
//
|
||||
// NamedLocation.h
|
||||
// hifi
|
||||
//
|
||||
// Created by Stojce Slavkovski on 2/1/14.
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef __hifi__NamedLocation__
|
||||
#define __hifi__NamedLocation__
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtx/string_cast.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
#include <QtCore>
|
||||
|
||||
class NamedLocation : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
NamedLocation(QString locationName, glm::vec3 location, glm::quat orientation, QString domain) {
|
||||
_locationName = locationName;
|
||||
_location = location;
|
||||
_orientation = orientation;
|
||||
_domain = domain;
|
||||
}
|
||||
|
||||
QString toJsonString();
|
||||
|
||||
bool isEmpty() { return _locationName.isNull() || _locationName.isEmpty(); }
|
||||
|
||||
void setLocationName(QString locationName) { _locationName = locationName; }
|
||||
QString locationName() { return _locationName; }
|
||||
|
||||
void setLocation(glm::vec3 location) { _location = location; }
|
||||
glm::vec3 location() { return _location; }
|
||||
|
||||
void setOrientation(glm::quat orentation) { _orientation = orentation; }
|
||||
glm::quat orientation() { return _orientation; }
|
||||
|
||||
void setDomain(QString domain) { _domain = domain; }
|
||||
QString domain() { return _domain; }
|
||||
|
||||
signals:
|
||||
void dataReceived(bool locationExists);
|
||||
|
||||
private:
|
||||
|
||||
QString _locationName;
|
||||
QString _createdBy;
|
||||
glm::vec3 _location;
|
||||
glm::quat _orientation;
|
||||
QString _domain;
|
||||
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__NamedLocation__) */
|
Loading…
Reference in a new issue