Merge branch 'master' of https://github.com/highfidelity/hifi into random_sounds

This commit is contained in:
Atlante45 2014-04-16 17:41:27 -07:00
commit 97490eba0e
20 changed files with 348 additions and 85 deletions

View file

@ -66,18 +66,6 @@ DomainServer::DomainServer(int argc, char* argv[]) :
LimitedNodeList* nodeList = LimitedNodeList::getInstance();
#if defined(IP_DONTFRAG) || defined(IP_MTU_DISCOVER)
qDebug() << "Making required DTLS changes to NodeList DTLS socket.";
int socketHandle = LimitedNodeList::getInstance()->getDTLSSocket().socketDescriptor();
#if defined(IP_DONTFRAG)
int optValue = 1;yea
setsockopt(socketHandle, IPPROTO_IP, IP_DONTFRAG, (const void*) optValue, sizeof(optValue));
#elif defined(IP_MTU_DISCOVER)
int optValue = 1;
setsockopt(socketHandle, IPPROTO_IP, IP_MTU_DISCOVER, (const void*) optValue, sizeof(optValue));
#endif
#endif
// connect our socket to read datagrams received on the DTLS socket
connect(&nodeList->getDTLSSocket(), &QUdpSocket::readyRead, this, &DomainServer::readAvailableDTLSDatagrams);
}
@ -311,8 +299,7 @@ const NodeSet STATICALLY_ASSIGNED_NODES = NodeSet() << NodeType::AudioMixer
<< NodeType::MetavoxelServer;
void DomainServer::addNodeToNodeListAndConfirmConnection(const QByteArray& packet, const HifiSockAddr& senderSockAddr,
const QJsonObject& authJsonObject) {
void DomainServer::addNodeToNodeListAndConfirmConnection(const QByteArray& packet, const HifiSockAddr& senderSockAddr) {
NodeType_t nodeType;
HifiSockAddr publicSockAddr, localSockAddr;
@ -336,7 +323,8 @@ void DomainServer::addNodeToNodeListAndConfirmConnection(const QByteArray& packe
// create a new session UUID for this node
QUuid nodeUUID = QUuid::createUuid();
SharedNodePointer newNode = LimitedNodeList::getInstance()->addOrUpdateNode(nodeUUID, nodeType, publicSockAddr, localSockAddr);
SharedNodePointer newNode = LimitedNodeList::getInstance()->addOrUpdateNode(nodeUUID, nodeType,
publicSockAddr, localSockAddr);
// when the newNode is created the linked data is also created
// if this was a static assignment set the UUID, set the sendingSockAddr
@ -345,12 +333,6 @@ void DomainServer::addNodeToNodeListAndConfirmConnection(const QByteArray& packe
nodeData->setStaticAssignmentUUID(assignmentUUID);
nodeData->setSendingSockAddr(senderSockAddr);
if (!authJsonObject.isEmpty()) {
// pull the connection secret from the authJsonObject and set it as the connection secret for this node
QUuid connectionSecret(authJsonObject["data"].toObject()["connection_secret"].toString());
newNode->setConnectionSecret(connectionSecret);
}
// reply back to the user with a PacketTypeDomainList
sendDomainListToNode(newNode, senderSockAddr, nodeInterestListFromPacket(packet, numPreInterestBytes));
}
@ -361,18 +343,6 @@ int DomainServer::parseNodeDataFromByteArray(NodeType_t& nodeType, HifiSockAddr&
QDataStream packetStream(packet);
packetStream.skipRawData(numBytesForPacketHeader(packet));
if (packetTypeForPacket(packet) == PacketTypeDomainConnectRequest) {
// we need to skip a quint8 that indicates if there is a registration token
// and potentially the registration token itself
quint8 hasRegistrationToken;
packetStream >> hasRegistrationToken;
if (hasRegistrationToken) {
QByteArray registrationToken;
packetStream >> registrationToken;
}
}
packetStream >> nodeType;
packetStream >> publicSockAddr >> localSockAddr;
@ -648,7 +618,11 @@ void DomainServer::processDatagram(const QByteArray& receivedPacket, const HifiS
if (nodeList->packetVersionAndHashMatch(receivedPacket)) {
PacketType requestType = packetTypeForPacket(receivedPacket);
if (requestType == PacketTypeDomainListRequest) {
if (requestType == PacketTypeDomainConnectRequest) {
// add this node to our NodeList
// and send back session UUID right away
addNodeToNodeListAndConfirmConnection(receivedPacket, senderSockAddr);
} else if (requestType == PacketTypeDomainListRequest) {
QUuid nodeUUID = uuidFromPacketHeader(receivedPacket);
if (!nodeUUID.isNull() && nodeList->nodeWithUUID(nodeUUID)) {
@ -665,12 +639,7 @@ void DomainServer::processDatagram(const QByteArray& receivedPacket, const HifiS
checkInNode->setLastHeardMicrostamp(timeNow);
sendDomainListToNode(checkInNode, senderSockAddr, nodeInterestListFromPacket(receivedPacket, numNodeInfoBytes));
} else {
// new node - add this node to our NodeList
// and send back session UUID right away
addNodeToNodeListAndConfirmConnection(receivedPacket, senderSockAddr);
}
} else if (requestType == PacketTypeNodeJsonStats) {
SharedNodePointer matchingNode = nodeList->sendingNodeForPacket(receivedPacket);
if (matchingNode) {

View file

@ -24,7 +24,7 @@
#include <Assignment.h>
#include <HTTPManager.h>
#include <NodeList.h>
#include <LimitedNodeList.h>
#include "DTLSServerSession.h"
@ -57,8 +57,7 @@ private:
void processDatagram(const QByteArray& receivedPacket, const HifiSockAddr& senderSockAddr);
void addNodeToNodeListAndConfirmConnection(const QByteArray& packet, const HifiSockAddr& senderSockAddr,
const QJsonObject& authJsonObject = QJsonObject());
void addNodeToNodeListAndConfirmConnection(const QByteArray& packet, const HifiSockAddr& senderSockAddr);
int parseNodeDataFromByteArray(NodeType_t& nodeType, HifiSockAddr& publicSockAddr,
HifiSockAddr& localSockAddr, const QByteArray& packet, const HifiSockAddr& senderSockAddr);
NodeSet nodeInterestListFromPacket(const QByteArray& packet, int numPreceedingBytes);

View file

@ -11,7 +11,8 @@ QLabel#advancedTuningLabel {
}
QPushButton#buttonBrowseHead,
QPushButton#buttonBrowseBody {
QPushButton#buttonBrowseBody,
QPushButton#buttonBrowseLocation {
background-image: url(styles/search.svg);
background-repeat: no-repeat;
background-position: center center;

View file

@ -25,7 +25,6 @@
#include <QMessageBox>
#include <QShortcut>
#include <QSlider>
#include <QStandardPaths>
#include <QUuid>
#include <QHBoxLayout>
@ -79,6 +78,9 @@ Menu::Menu() :
_lodToolsDialog(NULL),
_maxVoxels(DEFAULT_MAX_VOXELS_PER_SYSTEM),
_voxelSizeScale(DEFAULT_OCTREE_SIZE_SCALE),
_automaticAvatarLOD(true),
_avatarLODDecreaseFPS(DEFAULT_ADJUST_AVATAR_LOD_DOWN_FPS),
_avatarLODIncreaseFPS(ADJUST_LOD_UP_FPS),
_avatarLODDistanceMultiplier(DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER),
_boundaryLevelAdjust(0),
_maxVoxelPacketsPerSecond(DEFAULT_MAX_VOXEL_PPS),
@ -87,7 +89,8 @@ Menu::Menu() :
_fpsAverage(FIVE_SECONDS_OF_FRAMES),
_fastFPSAverage(ONE_SECOND_OF_FRAMES),
_loginAction(NULL),
_preferencesDialog(NULL)
_preferencesDialog(NULL),
_snapshotsLocation()
{
Application *appInstance = Application::getInstance();
@ -273,7 +276,7 @@ Menu::Menu() :
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Metavoxels, 0, true);
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::BuckyBalls, 0, true);
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Particles, 0, true);
addActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::LodTools, Qt::SHIFT | Qt::Key_L, this, SLOT(lodTools()));
QMenu* voxelOptionsMenu = developerMenu->addMenu("Voxel Options");
@ -286,7 +289,6 @@ Menu::Menu() :
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::VoxelTextures);
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::AmbientOcclusion);
addActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::LodTools, Qt::SHIFT | Qt::Key_L, this, SLOT(lodTools()));
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DontFadeOnVoxelServerChanges);
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DisableAutoAdjustLOD);
@ -415,7 +417,14 @@ void Menu::loadSettings(QSettings* settings) {
_maxVoxels = loadSetting(settings, "maxVoxels", DEFAULT_MAX_VOXELS_PER_SYSTEM);
_maxVoxelPacketsPerSecond = loadSetting(settings, "maxVoxelsPPS", DEFAULT_MAX_VOXEL_PPS);
_voxelSizeScale = loadSetting(settings, "voxelSizeScale", DEFAULT_OCTREE_SIZE_SCALE);
_automaticAvatarLOD = settings->value("automaticAvatarLOD", true).toBool();
_avatarLODDecreaseFPS = loadSetting(settings, "avatarLODDecreaseFPS", DEFAULT_ADJUST_AVATAR_LOD_DOWN_FPS);
_avatarLODIncreaseFPS = loadSetting(settings, "avatarLODIncreaseFPS", ADJUST_LOD_UP_FPS);
_avatarLODDistanceMultiplier = loadSetting(settings, "avatarLODDistanceMultiplier",
DEFAULT_AVATAR_LOD_DISTANCE_MULTIPLIER);
_boundaryLevelAdjust = loadSetting(settings, "boundaryLevelAdjust", 0);
_snapshotsLocation = settings->value("snapshotsLocation",
QStandardPaths::writableLocation(QStandardPaths::DesktopLocation)).toString();
settings->beginGroup("View Frustum Offset Camera");
// in case settings is corrupt or missing loadSetting() will check for NaN
@ -454,7 +463,12 @@ void Menu::saveSettings(QSettings* settings) {
settings->setValue("maxVoxels", _maxVoxels);
settings->setValue("maxVoxelsPPS", _maxVoxelPacketsPerSecond);
settings->setValue("voxelSizeScale", _voxelSizeScale);
settings->setValue("automaticAvatarLOD", _automaticAvatarLOD);
settings->setValue("avatarLODDecreaseFPS", _avatarLODDecreaseFPS);
settings->setValue("avatarLODIncreaseFPS", _avatarLODIncreaseFPS);
settings->setValue("avatarLODDistanceMultiplier", _avatarLODDistanceMultiplier);
settings->setValue("boundaryLevelAdjust", _boundaryLevelAdjust);
settings->setValue("snapshotsLocation", _snapshotsLocation);
settings->beginGroup("View Frustum Offset Camera");
settings->setValue("viewFrustumOffsetYaw", _viewFrustumOffset.yaw);
settings->setValue("viewFrustumOffsetPitch", _viewFrustumOffset.pitch);
@ -1158,27 +1172,27 @@ void Menu::autoAdjustLOD(float currentFPS) {
quint64 now = usecTimestampNow();
const float ADJUST_AVATAR_LOD_DOWN_FPS = 30.0f;
const quint64 ADJUST_AVATAR_LOD_DOWN_DELAY = 1000 * 1000;
if (_fastFPSAverage.getAverage() < ADJUST_AVATAR_LOD_DOWN_FPS) {
if (now - _lastAvatarDetailDrop > ADJUST_AVATAR_LOD_DOWN_DELAY) {
// attempt to lower the detail in proportion to the fps difference
float targetFps = (ADJUST_AVATAR_LOD_DOWN_FPS + ADJUST_LOD_UP_FPS) * 0.5f;
float averageFps = _fastFPSAverage.getAverage();
const float MAXIMUM_MULTIPLIER_SCALE = 2.0f;
const float MAXIMUM_DISTANCE_MULTIPLIER = 15.0f;
_avatarLODDistanceMultiplier = qMin(MAXIMUM_DISTANCE_MULTIPLIER, _avatarLODDistanceMultiplier *
(averageFps < EPSILON ? MAXIMUM_MULTIPLIER_SCALE : qMin(MAXIMUM_MULTIPLIER_SCALE, targetFps / averageFps)));
_lastAvatarDetailDrop = now;
if (_automaticAvatarLOD) {
if (_fastFPSAverage.getAverage() < _avatarLODDecreaseFPS) {
if (now - _lastAvatarDetailDrop > ADJUST_AVATAR_LOD_DOWN_DELAY) {
// attempt to lower the detail in proportion to the fps difference
float targetFps = (_avatarLODDecreaseFPS + _avatarLODIncreaseFPS) * 0.5f;
float averageFps = _fastFPSAverage.getAverage();
const float MAXIMUM_MULTIPLIER_SCALE = 2.0f;
_avatarLODDistanceMultiplier = qMin(MAXIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER, _avatarLODDistanceMultiplier *
(averageFps < EPSILON ? MAXIMUM_MULTIPLIER_SCALE :
qMin(MAXIMUM_MULTIPLIER_SCALE, targetFps / averageFps)));
_lastAvatarDetailDrop = now;
}
} else if (_fastFPSAverage.getAverage() > _avatarLODIncreaseFPS) {
// let the detail level creep slowly upwards
const float DISTANCE_DECREASE_RATE = 0.05f;
_avatarLODDistanceMultiplier = qMax(MINIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER,
_avatarLODDistanceMultiplier - DISTANCE_DECREASE_RATE);
}
} else if (_fastFPSAverage.getAverage() > ADJUST_LOD_UP_FPS) {
// let the detail level creep slowly upwards
const float DISTANCE_DECREASE_RATE = 0.05f;
const float MINIMUM_DISTANCE_MULTIPLIER = 0.1f;
_avatarLODDistanceMultiplier = qMax(MINIMUM_DISTANCE_MULTIPLIER,
_avatarLODDistanceMultiplier - DISTANCE_DECREASE_RATE);
}
bool changed = false;
quint64 elapsed = now - _lastAdjust;
@ -1502,3 +1516,10 @@ void Menu::removeMenuItem(const QString& menu, const QString& menuitem) {
QMenuBar::repaint();
};
QString Menu::getSnapshotsLocation() const {
if (_snapshotsLocation.isNull() || _snapshotsLocation.isEmpty() || QDir(_snapshotsLocation).exists() == false) {
return QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
}
return _snapshotsLocation;
}

View file

@ -12,10 +12,12 @@
#ifndef hifi_Menu_h
#define hifi_Menu_h
#include <QDir>
#include <QMenuBar>
#include <QHash>
#include <QKeySequence>
#include <QPointer>
#include <QStandardPaths>
#include <EventTypes.h>
#include <MenuItemProperties.h>
@ -27,6 +29,7 @@
const float ADJUST_LOD_DOWN_FPS = 40.0;
const float ADJUST_LOD_UP_FPS = 55.0;
const float DEFAULT_ADJUST_AVATAR_LOD_DOWN_FPS = 30.0f;
const quint64 ADJUST_LOD_DOWN_DELAY = 1000 * 1000 * 5;
const quint64 ADJUST_LOD_UP_DELAY = ADJUST_LOD_DOWN_DELAY * 2;
@ -37,6 +40,9 @@ const float ADJUST_LOD_UP_BY = 1.1f;
const float ADJUST_LOD_MIN_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE * 0.25f;
const float ADJUST_LOD_MAX_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE;
const float MINIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER = 0.1f;
const float MAXIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER = 15.0f;
enum FrustumDrawMode {
FRUSTUM_DRAW_MODE_ALL,
FRUSTUM_DRAW_MODE_VECTORS,
@ -79,6 +85,9 @@ public:
void setFieldOfView(float fieldOfView) { _fieldOfView = fieldOfView; }
float getFaceshiftEyeDeflection() const { return _faceshiftEyeDeflection; }
void setFaceshiftEyeDeflection(float faceshiftEyeDeflection) { _faceshiftEyeDeflection = faceshiftEyeDeflection; }
QString getSnapshotsLocation() const;
void setSnapshotsLocation(QString snapshotsLocation) { _snapshotsLocation = snapshotsLocation; }
BandwidthDialog* getBandwidthDialog() const { return _bandwidthDialog; }
FrustumDrawMode getFrustumDrawMode() const { return _frustumDrawMode; }
ViewFrustumOffset getViewFrustumOffset() const { return _viewFrustumOffset; }
@ -95,6 +104,13 @@ public:
void resetLODAdjust();
void setVoxelSizeScale(float sizeScale);
float getVoxelSizeScale() const { return _voxelSizeScale; }
void setAutomaticAvatarLOD(bool automaticAvatarLOD) { _automaticAvatarLOD = automaticAvatarLOD; }
bool getAutomaticAvatarLOD() const { return _automaticAvatarLOD; }
void setAvatarLODDecreaseFPS(float avatarLODDecreaseFPS) { _avatarLODDecreaseFPS = avatarLODDecreaseFPS; }
float getAvatarLODDecreaseFPS() const { return _avatarLODDecreaseFPS; }
void setAvatarLODIncreaseFPS(float avatarLODIncreaseFPS) { _avatarLODIncreaseFPS = avatarLODIncreaseFPS; }
float getAvatarLODIncreaseFPS() const { return _avatarLODIncreaseFPS; }
void setAvatarLODDistanceMultiplier(float multiplier) { _avatarLODDistanceMultiplier = multiplier; }
float getAvatarLODDistanceMultiplier() const { return _avatarLODDistanceMultiplier; }
void setBoundaryLevelAdjust(int boundaryLevelAdjust);
int getBoundaryLevelAdjust() const { return _boundaryLevelAdjust; }
@ -217,6 +233,9 @@ private:
LodToolsDialog* _lodToolsDialog;
int _maxVoxels;
float _voxelSizeScale;
bool _automaticAvatarLOD;
float _avatarLODDecreaseFPS;
float _avatarLODIncreaseFPS;
float _avatarLODDistanceMultiplier;
int _boundaryLevelAdjust;
QAction* _useVoxelShader;
@ -229,6 +248,7 @@ private:
QAction* _loginAction;
QPointer<PreferencesDialog> _preferencesDialog;
QAction* _chatAction;
QString _snapshotsLocation;
};
namespace MenuOption {

View file

@ -244,7 +244,6 @@ NetworkTexture::NetworkTexture(const QUrl& url, bool normalMap) :
if (!url.isValid()) {
_loaded = true;
return;
}
// default to white/blue

View file

@ -13,7 +13,9 @@
#include <QDialogButtonBox>
#include <QPalette>
#include <QCheckBox>
#include <QColor>
#include <QDoubleSpinBox>
#include <QSlider>
#include <QPushButton>
#include <QString>
@ -75,6 +77,27 @@ LodToolsDialog::LodToolsDialog(QWidget* parent) :
const int FEEDBACK_WIDTH = 350;
_feedback->setFixedWidth(FEEDBACK_WIDTH);
form->addRow("You can see... ", _feedback);
form->addRow("Automatic Avatar LOD Adjustment:", _automaticAvatarLOD = new QCheckBox());
_automaticAvatarLOD->setChecked(Menu::getInstance()->getAutomaticAvatarLOD());
connect(_automaticAvatarLOD, SIGNAL(toggled(bool)), SLOT(updateAvatarLODControls()));
form->addRow("Decrease Avatar LOD Below FPS:", _avatarLODDecreaseFPS = new QDoubleSpinBox());
_avatarLODDecreaseFPS->setValue(Menu::getInstance()->getAvatarLODDecreaseFPS());
_avatarLODDecreaseFPS->setDecimals(0);
connect(_avatarLODDecreaseFPS, SIGNAL(valueChanged(double)), SLOT(updateAvatarLODValues()));
form->addRow("Increase Avatar LOD Above FPS:", _avatarLODIncreaseFPS = new QDoubleSpinBox());
_avatarLODIncreaseFPS->setValue(Menu::getInstance()->getAvatarLODIncreaseFPS());
_avatarLODIncreaseFPS->setDecimals(0);
connect(_avatarLODIncreaseFPS, SIGNAL(valueChanged(double)), SLOT(updateAvatarLODValues()));
form->addRow("Avatar LOD:", _avatarLOD = new QDoubleSpinBox());
_avatarLOD->setDecimals(3);
_avatarLOD->setRange(1.0 / MAXIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER, 1.0 / MINIMUM_AVATAR_LOD_DISTANCE_MULTIPLIER);
_avatarLOD->setSingleStep(0.001);
_avatarLOD->setValue(1.0 / Menu::getInstance()->getAvatarLODDistanceMultiplier());
connect(_avatarLOD, SIGNAL(valueChanged(double)), SLOT(updateAvatarLODValues()));
// Add a button to reset
QPushButton* resetButton = new QPushButton("Reset");
@ -82,6 +105,8 @@ LodToolsDialog::LodToolsDialog(QWidget* parent) :
connect(resetButton,SIGNAL(clicked(bool)),this,SLOT(resetClicked(bool)));
this->QDialog::setLayout(form);
updateAvatarLODControls();
}
LodToolsDialog::~LodToolsDialog() {
@ -96,6 +121,39 @@ void LodToolsDialog::reloadSliders() {
_feedback->setText(Menu::getInstance()->getLODFeedbackText());
}
void LodToolsDialog::updateAvatarLODControls() {
QFormLayout* form = static_cast<QFormLayout*>(layout());
Menu::getInstance()->setAutomaticAvatarLOD(_automaticAvatarLOD->isChecked());
_avatarLODDecreaseFPS->setVisible(_automaticAvatarLOD->isChecked());
form->labelForField(_avatarLODDecreaseFPS)->setVisible(_automaticAvatarLOD->isChecked());
_avatarLODIncreaseFPS->setVisible(_automaticAvatarLOD->isChecked());
form->labelForField(_avatarLODIncreaseFPS)->setVisible(_automaticAvatarLOD->isChecked());
_avatarLOD->setVisible(!_automaticAvatarLOD->isChecked());
form->labelForField(_avatarLOD)->setVisible(!_automaticAvatarLOD->isChecked());
if (!_automaticAvatarLOD->isChecked()) {
_avatarLOD->setValue(1.0 / Menu::getInstance()->getAvatarLODDistanceMultiplier());
}
if (isVisible()) {
adjustSize();
}
}
void LodToolsDialog::updateAvatarLODValues() {
if (_automaticAvatarLOD->isChecked()) {
Menu::getInstance()->setAvatarLODDecreaseFPS(_avatarLODDecreaseFPS->value());
Menu::getInstance()->setAvatarLODIncreaseFPS(_avatarLODIncreaseFPS->value());
} else {
Menu::getInstance()->setAvatarLODDistanceMultiplier(1.0 / _avatarLOD->value());
}
}
void LodToolsDialog::sizeScaleValueChanged(int value) {
float realValue = value * TREE_SCALE;
Menu::getInstance()->setVoxelSizeScale(realValue);
@ -113,6 +171,9 @@ void LodToolsDialog::resetClicked(bool checked) {
//sizeScaleValueChanged(sliderValue);
_lodSize->setValue(sliderValue);
_boundaryLevelAdjust->setValue(0);
_automaticAvatarLOD->setChecked(true);
_avatarLODDecreaseFPS->setValue(DEFAULT_ADJUST_AVATAR_LOD_DOWN_FPS);
_avatarLODIncreaseFPS->setValue(ADJUST_LOD_UP_FPS);
}
void LodToolsDialog::reject() {

View file

@ -16,6 +16,9 @@
#include <QLabel>
#include <QSlider>
class QCheckBox;
class QDoubleSpinBox;
class LodToolsDialog : public QDialog {
Q_OBJECT
public:
@ -32,6 +35,8 @@ public slots:
void boundaryLevelValueChanged(int value);
void resetClicked(bool checked);
void reloadSliders();
void updateAvatarLODControls();
void updateAvatarLODValues();
protected:
@ -41,6 +46,10 @@ protected:
private:
QSlider* _lodSize;
QSlider* _boundaryLevelAdjust;
QCheckBox* _automaticAvatarLOD;
QDoubleSpinBox* _avatarLODDecreaseFPS;
QDoubleSpinBox* _avatarLODIncreaseFPS;
QDoubleSpinBox* _avatarLOD;
QLabel* _feedback;
};

View file

@ -28,6 +28,7 @@ PreferencesDialog::PreferencesDialog(QWidget* parent, Qt::WindowFlags flags) : F
connect(ui.buttonBrowseHead, &QPushButton::clicked, this, &PreferencesDialog::openHeadModelBrowser);
connect(ui.buttonBrowseBody, &QPushButton::clicked, this, &PreferencesDialog::openBodyModelBrowser);
connect(ui.buttonBrowseLocation, &QPushButton::clicked, this, &PreferencesDialog::openSnapshotLocationBrowser);
}
void PreferencesDialog::accept() {
@ -59,6 +60,17 @@ void PreferencesDialog::openBodyModelBrowser() {
modelBrowser.browse();
}
void PreferencesDialog::openSnapshotLocationBrowser() {
setWindowFlags(windowFlags() & ~Qt::WindowStaysOnTopHint);
QString dir = QFileDialog::getExistingDirectory(this, tr("Snapshots Location"),
QStandardPaths::writableLocation(QStandardPaths::DesktopLocation),
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
if (!dir.isNull() && !dir.isEmpty()) {
ui.snapshotLocationEdit->setText(dir);
}
setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
}
void PreferencesDialog::resizeEvent(QResizeEvent *resizeEvent) {
// keep buttons panel at the bottom
@ -94,6 +106,8 @@ void PreferencesDialog::loadPreferences() {
_skeletonURLString = myAvatar->getSkeletonModel().getURL().toString();
ui.skeletonURLEdit->setText(_skeletonURLString);
ui.snapshotLocationEdit->setText(menuInstance->getSnapshotsLocation());
ui.pupilDilationSlider->setValue(myAvatar->getHead()->getPupilDilation() *
ui.pupilDilationSlider->maximum());
@ -143,6 +157,10 @@ void PreferencesDialog::savePreferences() {
Application::getInstance()->bumpSettings();
}
if (!ui.snapshotLocationEdit->text().isEmpty() && QDir(ui.snapshotLocationEdit->text()).exists()) {
Menu::getInstance()->setSnapshotsLocation(ui.snapshotLocationEdit->text());
}
myAvatar->getHead()->setPupilDilation(ui.pupilDilationSlider->value() / (float)ui.pupilDilationSlider->maximum());
myAvatar->setLeanScale(ui.leanScaleSpin->value());
myAvatar->setClampedTargetScale(ui.avatarScaleSpin->value());

View file

@ -41,6 +41,7 @@ private slots:
void accept();
void setHeadUrl(QString modelUrl);
void setSkeletonUrl(QString modelUrl);
void openSnapshotLocationBrowser();
};

View file

@ -16,6 +16,7 @@
#include <FileUtils.h>
#include "Snapshot.h"
#include "Menu.h"
// filename format: hifi-snap-by-%username%-on-%date%_%time%_@-%location%.jpg
// %1 <= username, %2 <= date and time, %3 <= current location
@ -90,8 +91,12 @@ void Snapshot::saveSnapshot(QGLWidget* widget, Avatar* avatar) {
username.replace(QRegExp("[^A-Za-z0-9_]"), "-");
QDateTime now = QDateTime::currentDateTime();
QString fileName = FileUtils::standardPath(SNAPSHOTS_DIRECTORY);
QString fileName = Menu::getInstance()->getSnapshotsLocation();
if (!fileName.endsWith(QDir::separator())) {
fileName.append(QDir::separator());
}
fileName.append(QString(FILENAME_PATH_FORMAT.arg(username, now.toString(DATETIME_FORMAT), formattedLocation)));
shot.save(fileName, 0, 100);
}

View file

@ -156,7 +156,7 @@ color: #0e7077</string>
<x>0</x>
<y>0</y>
<width>615</width>
<height>833</height>
<height>936</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
@ -300,7 +300,7 @@ color: #0e7077</string>
<number>0</number>
</property>
<property name="buddy">
<cstring>faceURLEdit</cstring>
<cstring>snapshotLocationEdit</cstring>
</property>
</widget>
</item>
@ -476,6 +476,145 @@ color: #0e7077</string>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="avatarTitleLabel_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>40</height>
</size>
</property>
<property name="font">
<font>
<family>Arial</family>
<pointsize>20</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">color: #0e7077</string>
</property>
<property name="text">
<string>Snapshots</string>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="headLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="font">
<font>
<family>Arial</family>
<pointsize>16</pointsize>
</font>
</property>
<property name="styleSheet">
<string notr="true">color: #0e7077</string>
</property>
<property name="text">
<string>Place my Snapshots here:</string>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
<property name="margin">
<number>0</number>
</property>
<property name="buddy">
<cstring>snapshotLocationEdit</cstring>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="snapshotLocationEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>Arial</family>
</font>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="buttonBrowseLocation">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>30</width>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>30</width>
<height>30</height>
</size>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<property name="text">
<string/>
</property>
<property name="iconSize">
<size>
<width>30</width>
<height>30</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">

View file

@ -105,7 +105,21 @@ QUdpSocket& LimitedNodeList::getDTLSSocket() {
_dtlsSocket = new QUdpSocket(this);
_dtlsSocket->bind(QHostAddress::AnyIPv4, 0, QAbstractSocket::DontShareAddress);
qDebug() << "NodeList DTLS socket is listening on" << _dtlsSocket->localPort();
#if defined(IP_DONTFRAG) || defined(IP_MTU_DISCOVER)
qDebug() << "Making required DTLS changes to LimitedNodeList DTLS socket.";
int socketHandle = _dtlsSocket->socketDescriptor();
#if defined(IP_DONTFRAG)
int optValue = 1;
setsockopt(socketHandle, IPPROTO_IP, IP_DONTFRAG, reinterpret_cast<const void*>(&optValue), sizeof(optValue));
#elif defined(IP_MTU_DISCOVER)
int optValue = 1;
setsockopt(socketHandle, IPPROTO_IP, IP_MTU_DISCOVER, reinterpret_cast<const void*>(&optValue), sizeof(optValue));
#endif
#endif
qDebug() << "LimitedNodeList DTLS socket is listening on" << _dtlsSocket->localPort();
}
return *_dtlsSocket;
@ -331,7 +345,7 @@ void LimitedNodeList::processKillNode(const QByteArray& dataByteArray) {
killNodeWithUUID(nodeUUID);
}
SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, char nodeType,
SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType,
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) {
_nodeHashMutex.lock();

View file

@ -78,7 +78,7 @@ public:
SharedNodePointer nodeWithUUID(const QUuid& nodeUUID, bool blockingLock = true);
SharedNodePointer sendingNodeForPacket(const QByteArray& packet);
SharedNodePointer addOrUpdateNode(const QUuid& uuid, char nodeType,
SharedNodePointer addOrUpdateNode(const QUuid& uuid, NodeType_t nodeType,
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket);
SharedNodePointer updateSocketsForNode(const QUuid& uuid,
const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket);

View file

@ -42,7 +42,7 @@ const QString& NodeType::getNodeTypeName(NodeType_t nodeType) {
return matchedTypeName != TypeNameHash.end() ? matchedTypeName.value() : UNKNOWN_NodeType_t_NAME;
}
Node::Node(const QUuid& uuid, char type, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) :
Node::Node(const QUuid& uuid, NodeType_t type, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) :
_type(type),
_uuid(uuid),
_wakeTimestamp(QDateTime::currentMSecsSinceEpoch()),
@ -58,6 +58,7 @@ Node::Node(const QUuid& uuid, char type, const HifiSockAddr& publicSocket, const
_clockSkewUsec(0),
_mutex()
{
}
Node::~Node() {

View file

@ -45,7 +45,7 @@ namespace NodeType {
class Node : public QObject {
Q_OBJECT
public:
Node(const QUuid& uuid, char type, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket);
Node(const QUuid& uuid, NodeType_t type, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket);
~Node();
bool operator==(const Node& otherNode) const { return _uuid == otherNode._uuid; }

View file

@ -209,8 +209,10 @@ void NodeList::reset() {
// clear the domain connection information
_domainHandler.clearConnectionInfo();
// also disconnect from the DTLS socket readyRead() so it can handle handshaking
disconnect(_dtlsSocket, 0, this, 0);
// if we setup the DTLS socket, also disconnect from the DTLS socket readyRead() so it can handle handshaking
if (_dtlsSocket) {
disconnect(_dtlsSocket, 0, this, 0);
}
}
void NodeList::addNodeTypeToInterestSet(NodeType_t nodeTypeToAdd) {
@ -376,10 +378,14 @@ void NodeList::sendDomainServerCheckIn() {
}
}
// construct the DS check in packet
QUuid packetUUID = (!_sessionUUID.isNull() ? _sessionUUID : _domainHandler.getAssignmentUUID());
PacketType domainPacketType = _sessionUUID.isNull()
? PacketTypeDomainConnectRequest : PacketTypeDomainListRequest;
QByteArray domainServerPacket = byteArrayWithPopulatedHeader(PacketTypeDomainListRequest, packetUUID);
// construct the DS check in packet
QUuid packetUUID = (domainPacketType == PacketTypeDomainListRequest
? _sessionUUID : _domainHandler.getAssignmentUUID());
QByteArray domainServerPacket = byteArrayWithPopulatedHeader(domainPacketType, packetUUID);
QDataStream packetStream(&domainServerPacket, QIODevice::Append);
// pack our data to send to the domain-server

View file

@ -55,7 +55,7 @@ PacketVersion versionForPacketType(PacketType type) {
return 1;
case PacketTypeDomainList:
case PacketTypeDomainListRequest:
return 2;
return 3;
case PacketTypeCreateAssignment:
case PacketTypeRequestAssignment:
return 2;

View file

@ -58,7 +58,7 @@ enum PacketType {
PacketTypeMetavoxelData,
PacketTypeAvatarIdentity,
PacketTypeAvatarBillboard,
PacketTypeDomainConnectRequest, // reusable
PacketTypeDomainConnectRequest,
PacketTypeDomainServerRequireDTLS,
PacketTypeNodeJsonStats,
};
@ -66,7 +66,8 @@ enum PacketType {
typedef char PacketVersion;
const QSet<PacketType> NON_VERIFIED_PACKETS = QSet<PacketType>()
<< PacketTypeDomainServerRequireDTLS << PacketTypeDomainList << PacketTypeDomainListRequest
<< PacketTypeDomainServerRequireDTLS << PacketTypeDomainConnectRequest
<< PacketTypeDomainList << PacketTypeDomainListRequest
<< PacketTypeCreateAssignment << PacketTypeRequestAssignment << PacketTypeStunResponse
<< PacketTypeNodeJsonStats;

View file

@ -61,8 +61,7 @@ void FileUtils::locateFile(QString filePath) {
QString FileUtils::standardPath(QString subfolder) {
// standard path
// Mac: ~/Library/Application Support/Interface
QString path = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation);
path.append("/Interface");
QString path = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
if (!subfolder.startsWith("/")) {
subfolder.prepend("/");