mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-26 09:33:20 +02:00
commit
c24abb644d
8 changed files with 478 additions and 94 deletions
|
@ -48,7 +48,7 @@ configure_file(InterfaceVersion.h.in "${PROJECT_BINARY_DIR}/includes/InterfaceVe
|
||||||
|
|
||||||
# grab the implementation and header files from src dirs
|
# grab the implementation and header files from src dirs
|
||||||
file(GLOB INTERFACE_SRCS src/*.cpp src/*.h)
|
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)
|
file(GLOB_RECURSE SUBDIR_SRCS src/${SUBDIR}/*.cpp src/${SUBDIR}/*.h)
|
||||||
set(INTERFACE_SRCS ${INTERFACE_SRCS} "${SUBDIR_SRCS}")
|
set(INTERFACE_SRCS ${INTERFACE_SRCS} "${SUBDIR_SRCS}")
|
||||||
endforeach(SUBDIR)
|
endforeach(SUBDIR)
|
||||||
|
|
|
@ -113,18 +113,18 @@
|
||||||
<context>
|
<context>
|
||||||
<name>Menu</name>
|
<name>Menu</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="src/Menu.cpp" line="429"/>
|
<location filename="src/Menu.cpp" line="437"/>
|
||||||
<source>Open .ini config file</source>
|
<source>Open .ini config file</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="src/Menu.cpp" line="431"/>
|
<location filename="src/Menu.cpp" line="439"/>
|
||||||
<location filename="src/Menu.cpp" line="443"/>
|
<location filename="src/Menu.cpp" line="451"/>
|
||||||
<source>Text files (*.ini)</source>
|
<source>Text files (*.ini)</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="src/Menu.cpp" line="441"/>
|
<location filename="src/Menu.cpp" line="449"/>
|
||||||
<source>Save .ini config file</source>
|
<source>Save .ini config file</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QMenuBar>
|
#include <QMenuBar>
|
||||||
|
#include <QMessageBox>
|
||||||
#include <QShortcut>
|
#include <QShortcut>
|
||||||
#include <QSlider>
|
#include <QSlider>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
|
@ -36,6 +37,7 @@
|
||||||
#include "InfoView.h"
|
#include "InfoView.h"
|
||||||
#include "ui/MetavoxelEditor.h"
|
#include "ui/MetavoxelEditor.h"
|
||||||
|
|
||||||
|
|
||||||
Menu* Menu::_instance = NULL;
|
Menu* Menu::_instance = NULL;
|
||||||
|
|
||||||
Menu* Menu::getInstance() {
|
Menu* Menu::getInstance() {
|
||||||
|
@ -78,7 +80,7 @@ Menu::Menu() :
|
||||||
_loginAction(NULL)
|
_loginAction(NULL)
|
||||||
{
|
{
|
||||||
Application *appInstance = Application::getInstance();
|
Application *appInstance = Application::getInstance();
|
||||||
|
|
||||||
QMenu* fileMenu = addMenu("File");
|
QMenu* fileMenu = addMenu("File");
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
|
@ -116,13 +118,18 @@ Menu::Menu() :
|
||||||
addActionToQMenuAndActionHash(fileMenu,
|
addActionToQMenuAndActionHash(fileMenu,
|
||||||
MenuOption::GoToDomain,
|
MenuOption::GoToDomain,
|
||||||
Qt::CTRL | Qt::Key_D,
|
Qt::CTRL | Qt::Key_D,
|
||||||
this,
|
this,
|
||||||
SLOT(goToDomainDialog()));
|
SLOT(goToDomainDialog()));
|
||||||
addActionToQMenuAndActionHash(fileMenu,
|
addActionToQMenuAndActionHash(fileMenu,
|
||||||
MenuOption::GoToLocation,
|
MenuOption::GoToLocation,
|
||||||
Qt::CTRL | Qt::SHIFT | Qt::Key_L,
|
Qt::CTRL | Qt::SHIFT | Qt::Key_L,
|
||||||
this,
|
this,
|
||||||
SLOT(goToLocation()));
|
SLOT(goToLocation()));
|
||||||
|
addActionToQMenuAndActionHash(fileMenu,
|
||||||
|
MenuOption::NameLocation,
|
||||||
|
Qt::CTRL | Qt::Key_N,
|
||||||
|
this,
|
||||||
|
SLOT(nameLocation()));
|
||||||
addActionToQMenuAndActionHash(fileMenu,
|
addActionToQMenuAndActionHash(fileMenu,
|
||||||
MenuOption::GoTo,
|
MenuOption::GoTo,
|
||||||
Qt::Key_At,
|
Qt::Key_At,
|
||||||
|
@ -421,6 +428,7 @@ void Menu::saveSettings(QSettings* settings) {
|
||||||
scanMenuBar(&saveAction, settings);
|
scanMenuBar(&saveAction, settings);
|
||||||
Application::getInstance()->getAvatar()->saveData(settings);
|
Application::getInstance()->getAvatar()->saveData(settings);
|
||||||
NodeList::getInstance()->saveData(settings);
|
NodeList::getInstance()->saveData(settings);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Menu::importSettings() {
|
void Menu::importSettings() {
|
||||||
|
@ -864,67 +872,11 @@ void Menu::goToDomainDialog() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Menu::goToOrientation(QString orientation) {
|
void Menu::goToOrientation(QString orientation) {
|
||||||
|
LocationManager::getInstance().goToDestination(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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Menu::goToDestination(QString destination) {
|
bool Menu::goToDestination(QString destination) {
|
||||||
|
return LocationManager::getInstance().goToDestination(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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Menu::goTo() {
|
void Menu::goTo() {
|
||||||
|
@ -939,25 +891,33 @@ void Menu::goTo() {
|
||||||
|
|
||||||
int dialogReturn = gotoDialog.exec();
|
int dialogReturn = gotoDialog.exec();
|
||||||
if (dialogReturn == QDialog::Accepted && !gotoDialog.textValue().isEmpty()) {
|
if (dialogReturn == QDialog::Accepted && !gotoDialog.textValue().isEmpty()) {
|
||||||
|
LocationManager* manager = &LocationManager::getInstance();
|
||||||
destination = gotoDialog.textValue();
|
manager->goTo(gotoDialog.textValue());
|
||||||
|
connect(manager, &LocationManager::multipleDestinationsFound, this, &Menu::multipleDestinationsDecision);
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sendFakeEnterEvent();
|
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() {
|
void Menu::goToLocation() {
|
||||||
MyAvatar* myAvatar = Application::getInstance()->getAvatar();
|
MyAvatar* myAvatar = Application::getInstance()->getAvatar();
|
||||||
glm::vec3 avatarPos = myAvatar->getPosition();
|
glm::vec3 avatarPos = myAvatar->getPosition();
|
||||||
|
@ -980,6 +940,69 @@ void Menu::goToLocation() {
|
||||||
sendFakeEnterEvent();
|
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() {
|
void Menu::pasteToVoxel() {
|
||||||
QInputDialog pasteToOctalCodeDialog(Application::getInstance()->getWindow());
|
QInputDialog pasteToOctalCodeDialog(Application::getInstance()->getWindow());
|
||||||
pasteToOctalCodeDialog.setWindowTitle("Paste to Voxel");
|
pasteToOctalCodeDialog.setWindowTitle("Paste to Voxel");
|
||||||
|
@ -1246,17 +1269,6 @@ void Menu::addAvatarCollisionSubMenu(QMenu* overMenu) {
|
||||||
0, true, avatar, SLOT(updateCollisionFlags()));
|
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) {
|
QAction* Menu::getActionFromName(const QString& menuName, QMenu* menu) {
|
||||||
QList<QAction*> menuActions;
|
QList<QAction*> menuActions;
|
||||||
if (menu) {
|
if (menu) {
|
||||||
|
|
|
@ -18,7 +18,8 @@
|
||||||
#include <MenuItemProperties.h>
|
#include <MenuItemProperties.h>
|
||||||
#include <OctreeConstants.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_DOWN_FPS = 40.0;
|
||||||
const float ADJUST_LOD_UP_FPS = 55.0;
|
const float ADJUST_LOD_UP_FPS = 55.0;
|
||||||
|
@ -138,6 +139,7 @@ private slots:
|
||||||
void editPreferences();
|
void editPreferences();
|
||||||
void goToDomainDialog();
|
void goToDomainDialog();
|
||||||
void goToLocation();
|
void goToLocation();
|
||||||
|
void nameLocation();
|
||||||
void bandwidthDetailsClosed();
|
void bandwidthDetailsClosed();
|
||||||
void octreeStatsDetailsClosed();
|
void octreeStatsDetailsClosed();
|
||||||
void lodToolsClosed();
|
void lodToolsClosed();
|
||||||
|
@ -147,6 +149,8 @@ private slots:
|
||||||
void showChat();
|
void showChat();
|
||||||
void toggleChat();
|
void toggleChat();
|
||||||
void audioMuteToggled();
|
void audioMuteToggled();
|
||||||
|
void namedLocationCreated(LocationManager::NamedLocationCreateResponse response);
|
||||||
|
void multipleDestinationsDecision(const QJsonObject& userData, const QJsonObject& placeData);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static Menu* _instance;
|
static Menu* _instance;
|
||||||
|
@ -248,6 +252,7 @@ namespace MenuOption {
|
||||||
const QString GlowMode = "Cycle Glow Mode";
|
const QString GlowMode = "Cycle Glow Mode";
|
||||||
const QString GoToDomain = "Go To Domain...";
|
const QString GoToDomain = "Go To Domain...";
|
||||||
const QString GoToLocation = "Go To Location...";
|
const QString GoToLocation = "Go To Location...";
|
||||||
|
const QString NameLocation = "Name this location";
|
||||||
const QString GoTo = "Go To...";
|
const QString GoTo = "Go To...";
|
||||||
const QString IncreaseAvatarSize = "Increase Avatar Size";
|
const QString IncreaseAvatarSize = "Increase Avatar Size";
|
||||||
const QString IncreaseVoxelSize = "Increase Voxel 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