Merge pull request #1537 from ZappoMan/stephens_requests

added option to disable local cache file
This commit is contained in:
Stephen Birarda 2014-01-15 17:07:43 -08:00
commit d7388c2288
3 changed files with 226 additions and 216 deletions

View file

@ -165,7 +165,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
}
NodeList* nodeList = NodeList::createInstance(NODE_TYPE_AGENT, listenPort);
// connect our processDatagrams slot to the QUDPSocket readyRead() signal
connect(&nodeList->getNodeSocket(), SIGNAL(readyRead()), SLOT(processDatagrams()));
@ -176,7 +176,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
connect(audioThread, SIGNAL(started()), &_audio, SLOT(start()));
audioThread->start();
connect(nodeList, SIGNAL(domainChanged(const QString&)), SLOT(domainChanged(const QString&)));
connect(nodeList, SIGNAL(nodeKilled(SharedNodePointer)), SLOT(nodeKilled(SharedNodePointer)));
@ -209,7 +209,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
#endif
// tell the NodeList instance who to tell the domain server we care about
const char nodeTypesOfInterest[] = {NODE_TYPE_AUDIO_MIXER, NODE_TYPE_AVATAR_MIXER, NODE_TYPE_VOXEL_SERVER,
const char nodeTypesOfInterest[] = {NODE_TYPE_AUDIO_MIXER, NODE_TYPE_AVATAR_MIXER, NODE_TYPE_VOXEL_SERVER,
NODE_TYPE_PARTICLE_SERVER, NODE_TYPE_METAVOXEL_SERVER};
nodeList->setNodeTypesOfInterest(nodeTypesOfInterest, sizeof(nodeTypesOfInterest));
@ -1416,8 +1416,10 @@ void Application::terminate() {
_voxelHideShowThread.terminate();
_voxelEditSender.terminate();
_particleEditSender.terminate();
_persistThread->terminate();
_persistThread = NULL;
if (_persistThread) {
_persistThread->terminate();
_persistThread = NULL;
}
}
static Avatar* processAvatarMessageHeader(unsigned char*& packetData, size_t& dataBytes) {
@ -1966,12 +1968,12 @@ Avatar* Application::findLookatTargetAvatar(const glm::vec3& mouseRayOrigin, con
if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) {
Avatar* avatar = (Avatar*)node->getLinkedData();
float distance;
if (avatar->findRayIntersection(mouseRayOrigin, mouseRayDirection, distance)) {
// rescale to compensate for head embiggening
eyePosition = (avatar->getHead().calculateAverageEyePosition() - avatar->getHead().getScalePivot()) *
(avatar->getScale() / avatar->getHead().getScale()) + avatar->getHead().getScalePivot();
_lookatIndicatorScale = avatar->getHead().getScale();
_lookatOtherPosition = avatar->getHead().getPosition();
nodeUUID = avatar->getOwningNode()->getUUID();
@ -1979,7 +1981,7 @@ Avatar* Application::findLookatTargetAvatar(const glm::vec3& mouseRayOrigin, con
}
}
}
return NULL;
}
@ -2021,7 +2023,7 @@ void Application::renderHighlightVoxel(VoxelDetail voxel) {
void Application::updateAvatars(float deltaTime, glm::vec3 mouseRayOrigin, glm::vec3 mouseRayDirection) {
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
PerformanceWarning warn(showWarnings, "Application::updateAvatars()");
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
QMutexLocker(&node->getMutex());
if (node->getLinkedData()) {
@ -2038,11 +2040,11 @@ void Application::updateAvatars(float deltaTime, glm::vec3 mouseRayOrigin, glm::
for (vector<Avatar*>::iterator fade = _avatarFades.begin(); fade != _avatarFades.end(); fade++) {
Avatar* avatar = *fade;
const float SHRINK_RATE = 0.9f;
avatar->setTargetScale(avatar->getScale() * SHRINK_RATE);
const float MIN_FADE_SCALE = 0.001;
if (avatar->getTargetScale() < MIN_FADE_SCALE) {
delete avatar;
_avatarFades.erase(fade--);
@ -2260,6 +2262,7 @@ void Application::updateMouseVoxels(float deltaTime, glm::vec3& mouseRayOrigin,
}
}
void Application::updateHandAndTouch(float deltaTime) {
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
PerformanceWarning warn(showWarnings, "Application::updateHandAndTouch()");
@ -2303,7 +2306,9 @@ void Application::updateThreads(float deltaTime) {
_voxelHideShowThread.threadRoutine();
_voxelEditSender.threadRoutine();
_particleEditSender.threadRoutine();
_persistThread->threadRoutine();
if (_persistThread) {
_persistThread->threadRoutine();
}
}
}
@ -2613,32 +2618,32 @@ void Application::queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, Node
int totalServers = 0;
int inViewServers = 0;
int unknownJurisdictionServers = 0;
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
// only send to the NodeTypes that are serverType
if (node->getActiveSocket() != NULL && node->getType() == serverType) {
totalServers++;
// get the server bounds for this server
QUuid nodeUUID = node->getUUID();
// if we haven't heard from this voxel server, go ahead and send it a query, so we
// can get the jurisdiction...
if (jurisdictions.find(nodeUUID) == jurisdictions.end()) {
unknownJurisdictionServers++;
} else {
const JurisdictionMap& map = (jurisdictions)[nodeUUID];
unsigned char* rootCode = map.getRootOctalCode();
if (rootCode) {
VoxelPositionSize rootDetails;
voxelDetailsForCode(rootCode, rootDetails);
AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
serverBounds.scale(TREE_SCALE);
ViewFrustum::location serverFrustumLocation = _viewFrustum.boxInFrustum(serverBounds);
if (serverFrustumLocation != ViewFrustum::OUTSIDE) {
inViewServers++;
}
@ -2671,20 +2676,20 @@ void Application::queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, Node
if (wantExtraDebugging && unknownJurisdictionServers > 0) {
qDebug("perServerPPS: %d perUnknownServer: %d", perServerPPS, perUnknownServer);
}
NodeList* nodeList = NodeList::getInstance();
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
// only send to the NodeTypes that are serverType
if (node->getActiveSocket() != NULL && node->getType() == serverType) {
// get the server bounds for this server
QUuid nodeUUID = node->getUUID();
bool inView = false;
bool unknownView = false;
// if we haven't heard from this voxel server, go ahead and send it a query, so we
// can get the jurisdiction...
if (jurisdictions.find(nodeUUID) == jurisdictions.end()) {
@ -2694,15 +2699,15 @@ void Application::queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, Node
}
} else {
const JurisdictionMap& map = (jurisdictions)[nodeUUID];
unsigned char* rootCode = map.getRootOctalCode();
if (rootCode) {
VoxelPositionSize rootDetails;
voxelDetailsForCode(rootCode, rootDetails);
AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
serverBounds.scale(TREE_SCALE);
ViewFrustum::location serverFrustumLocation = _viewFrustum.boxInFrustum(serverBounds);
if (serverFrustumLocation != ViewFrustum::OUTSIDE) {
inView = true;
@ -2715,7 +2720,7 @@ void Application::queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, Node
}
}
}
if (inView) {
_voxelQuery.setMaxOctreePacketsPerSecond(perServerPPS);
} else if (unknownView) {
@ -2723,7 +2728,7 @@ void Application::queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, Node
qDebug() << "no known jurisdiction for node " << *node << ", give it budget of "
<< perUnknownServer << " to send us jurisdiction.";
}
// set the query's position/orientation to be degenerate in a manner that will get the scene quickly
// If there's only one server, then don't do this, and just let the normal voxel query pass through
// as expected... this way, we will actually get a valid scene if there is one to be seen
@ -2747,24 +2752,24 @@ void Application::queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, Node
}
// set up the packet for sending...
unsigned char* endOfVoxelQueryPacket = voxelQueryPacket;
// insert packet type/version and node UUID
endOfVoxelQueryPacket += populateTypeAndVersion(endOfVoxelQueryPacket, packetType);
QByteArray ownerUUID = nodeList->getOwnerUUID().toRfc4122();
memcpy(endOfVoxelQueryPacket, ownerUUID.constData(), ownerUUID.size());
endOfVoxelQueryPacket += ownerUUID.size();
// encode the query data...
endOfVoxelQueryPacket += _voxelQuery.getBroadcastData(endOfVoxelQueryPacket);
int packetLength = endOfVoxelQueryPacket - voxelQueryPacket;
// make sure we still have an active socket
if (node->getActiveSocket()) {
nodeList->getNodeSocket().writeDatagram((char*) voxelQueryPacket, packetLength,
node->getActiveSocket()->getAddress(), node->getActiveSocket()->getPort());
}
// Feed number of bytes to corresponding channel of the bandwidth meter
_bandwidthMeter.outputStream(BandwidthMeter::VOXELS).updateValue(packetLength);
}
@ -3244,7 +3249,7 @@ void Application::displayOverlay() {
char nodes[100];
int totalAvatars = 0, totalServers = 0;
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
node->getType() == NODE_TYPE_AGENT ? totalAvatars++ : totalServers++;
}
@ -3358,7 +3363,7 @@ void Application::displayStats() {
// Now handle voxel servers, since there could be more than one, we average their ping times
unsigned long totalPingVoxel = 0;
int voxelServerCount = 0;
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
totalPingVoxel += node->getPingMs();
@ -3368,7 +3373,7 @@ void Application::displayStats() {
}
}
}
if (voxelServerCount) {
pingVoxel = totalPingVoxel/voxelServerCount;
}
@ -3704,10 +3709,10 @@ void Application::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) {
if (!selfAvatarOnly) {
// Render avatars of other nodes
NodeList* nodeList = NodeList::getInstance();
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
QMutexLocker(&node->getMutex());
if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) {
Avatar *avatar = (Avatar *)node->getLinkedData();
if (!avatar->isInitialized()) {
@ -4205,28 +4210,28 @@ void Application::processDatagrams() {
MAX_PACKET_SIZE,
senderSockAddr.getAddressPointer(),
senderSockAddr.getPortPointer()))) {
_packetCount++;
_bytesCount += bytesReceived;
if (packetVersionMatch(_incomingPacket)) {
// only process this packet if we have a match on the packet version
switch (_incomingPacket[0]) {
case PACKET_TYPE_TRANSMITTER_DATA_V2:
// V2 = IOS transmitter app
_myTransmitter.processIncomingData(_incomingPacket, bytesReceived);
break;
case PACKET_TYPE_MIXED_AUDIO:
QMetaObject::invokeMethod(&_audio, "addReceivedAudioToBuffer", Qt::QueuedConnection,
Q_ARG(QByteArray, QByteArray((char*) _incomingPacket, bytesReceived)));
break;
case PACKET_TYPE_PARTICLE_ADD_RESPONSE:
// look up our ParticleEditHanders....
ParticleEditHandle::handleAddResponse(_incomingPacket, bytesReceived);
break;
case PACKET_TYPE_PARTICLE_DATA:
case PACKET_TYPE_VOXEL_DATA:
case PACKET_TYPE_VOXEL_ERASE:
@ -4234,7 +4239,7 @@ void Application::processDatagrams() {
case PACKET_TYPE_ENVIRONMENT_DATA: {
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
"Application::networkReceive()... _voxelProcessor.queueReceivedPacket()");
bool wantExtraDebugging = getLogger()->extraDebugging();
if (wantExtraDebugging && _incomingPacket[0] == PACKET_TYPE_VOXEL_DATA) {
int numBytesPacketHeader = numBytesForPacketHeader(_incomingPacket);
@ -4246,10 +4251,10 @@ void Application::processDatagrams() {
dataAt += sizeof(VOXEL_PACKET_SENT_TIME);
VOXEL_PACKET_SENT_TIME arrivedAt = usecTimestampNow();
int flightTime = arrivedAt - sentAt;
printf("got PACKET_TYPE_VOXEL_DATA, sequence:%d flightTime:%d\n", sequence, flightTime);
}
// add this packet to our list of voxel packets and process them on the voxel processing
_voxelProcessor.queueReceivedPacket(senderSockAddr, _incomingPacket, bytesReceived);
break;
@ -4392,10 +4397,13 @@ void Application::updateLocalOctreeCache(bool firstTime) {
QString localVoxelCacheFileName = getLocalVoxelCacheFileName();
const int LOCAL_CACHE_PERSIST_INTERVAL = 1000 * 10; // every 10 seconds
_persistThread = new OctreePersistThread(_voxels.getTree(),
localVoxelCacheFileName.toLocal8Bit().constData(),LOCAL_CACHE_PERSIST_INTERVAL);
qDebug() << "updateLocalOctreeCache()... localVoxelCacheFileName=" << localVoxelCacheFileName;
if (!Menu::getInstance()->isOptionChecked(MenuOption::DisableLocalVoxelCache)) {
_persistThread = new OctreePersistThread(_voxels.getTree(),
localVoxelCacheFileName.toLocal8Bit().constData(),LOCAL_CACHE_PERSIST_INTERVAL);
qDebug() << "updateLocalOctreeCache()... localVoxelCacheFileName=" << localVoxelCacheFileName;
}
if (_persistThread) {
_voxels.beginLoadingLocalVoxelCache(); // while local voxels are importing, don't do individual node VBO updates

View file

@ -37,18 +37,18 @@ Menu* Menu::_instance = NULL;
Menu* Menu::getInstance() {
static QMutex menuInstanceMutex;
// lock the menu instance mutex to make sure we don't race and create two menus and crash
menuInstanceMutex.lock();
if (!_instance) {
qDebug("First call to Menu::getInstance() - initing menu.");
_instance = new Menu();
}
menuInstanceMutex.unlock();
return _instance;
}
@ -72,9 +72,9 @@ Menu::Menu() :
_maxVoxelPacketsPerSecond(DEFAULT_MAX_VOXEL_PPS)
{
Application *appInstance = Application::getInstance();
QMenu* fileMenu = addMenu("File");
#ifdef Q_OS_MAC
addActionToQMenuAndActionHash(fileMenu,
MenuOption::AboutApp,
@ -83,7 +83,7 @@ Menu::Menu() :
SLOT(aboutApp()),
QAction::AboutRole);
#endif
(addActionToQMenuAndActionHash(fileMenu,
MenuOption::Login,
0,
@ -97,7 +97,7 @@ Menu::Menu() :
addDisabledActionAndSeparator(fileMenu, "Voxels");
addActionToQMenuAndActionHash(fileMenu, MenuOption::ExportVoxels, Qt::CTRL | Qt::Key_E, appInstance, SLOT(exportVoxels()));
addActionToQMenuAndActionHash(fileMenu, MenuOption::ImportVoxels, Qt::CTRL | Qt::Key_I, appInstance, SLOT(importVoxels()));
addDisabledActionAndSeparator(fileMenu, "Go");
addActionToQMenuAndActionHash(fileMenu,
MenuOption::GoHome,
@ -120,45 +120,45 @@ Menu::Menu() :
this,
SLOT(goToUser()));
addDisabledActionAndSeparator(fileMenu, "Settings");
addActionToQMenuAndActionHash(fileMenu, MenuOption::SettingsImport, 0, this, SLOT(importSettings()));
addActionToQMenuAndActionHash(fileMenu, MenuOption::SettingsExport, 0, this, SLOT(exportSettings()));
addDisabledActionAndSeparator(fileMenu, "Devices");
addActionToQMenuAndActionHash(fileMenu, MenuOption::Pair, 0, PairingHandler::getInstance(), SLOT(sendPairRequest()));
addCheckableActionToQMenuAndActionHash(fileMenu, MenuOption::TransmitterDrive, 0, true);
addActionToQMenuAndActionHash(fileMenu,
MenuOption::Quit,
Qt::CTRL | Qt::Key_Q,
appInstance,
SLOT(quit()),
QAction::QuitRole);
QMenu* editMenu = addMenu("Edit");
addActionToQMenuAndActionHash(editMenu,
MenuOption::Preferences,
Qt::CTRL | Qt::Key_Comma,
this,
SLOT(editPreferences()),
QAction::PreferencesRole);
addDisabledActionAndSeparator(editMenu, "Voxels");
addActionToQMenuAndActionHash(editMenu, MenuOption::CutVoxels, Qt::CTRL | Qt::Key_X, appInstance, SLOT(cutVoxels()));
addActionToQMenuAndActionHash(editMenu, MenuOption::CopyVoxels, Qt::CTRL | Qt::Key_C, appInstance, SLOT(copyVoxels()));
addActionToQMenuAndActionHash(editMenu, MenuOption::PasteVoxels, Qt::CTRL | Qt::Key_V, appInstance, SLOT(pasteVoxels()));
addActionToQMenuAndActionHash(editMenu, MenuOption::NudgeVoxels, Qt::CTRL | Qt::Key_N, appInstance, SLOT(nudgeVoxels()));
#ifdef __APPLE__
addActionToQMenuAndActionHash(editMenu, MenuOption::DeleteVoxels, Qt::Key_Backspace, appInstance, SLOT(deleteVoxels()));
#else
addActionToQMenuAndActionHash(editMenu, MenuOption::DeleteVoxels, Qt::Key_Delete, appInstance, SLOT(deleteVoxels()));
#endif
addDisabledActionAndSeparator(editMenu, "Physics");
addCheckableActionToQMenuAndActionHash(editMenu, MenuOption::Gravity, Qt::SHIFT | Qt::Key_G, true);
addCheckableActionToQMenuAndActionHash(editMenu,
@ -167,47 +167,47 @@ Menu::Menu() :
true,
appInstance->getAvatar(),
SLOT(setWantCollisionsOn(bool)));
QMenu* toolsMenu = addMenu("Tools");
_voxelModeActionsGroup = new QActionGroup(this);
_voxelModeActionsGroup->setExclusive(false);
QAction* addVoxelMode = addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::VoxelAddMode, Qt::Key_V);
_voxelModeActionsGroup->addAction(addVoxelMode);
QAction* deleteVoxelMode = addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::VoxelDeleteMode, Qt::Key_R);
_voxelModeActionsGroup->addAction(deleteVoxelMode);
QAction* colorVoxelMode = addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::VoxelColorMode, Qt::Key_B);
_voxelModeActionsGroup->addAction(colorVoxelMode);
QAction* selectVoxelMode = addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::VoxelSelectMode, Qt::Key_O);
_voxelModeActionsGroup->addAction(selectVoxelMode);
QAction* getColorMode = addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::VoxelGetColorMode, Qt::Key_G);
_voxelModeActionsGroup->addAction(getColorMode);
addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::ClickToFly);
// connect each of the voxel mode actions to the updateVoxelModeActionsSlot
foreach (QAction* action, _voxelModeActionsGroup->actions()) {
connect(action, SIGNAL(triggered()), this, SLOT(updateVoxelModeActions()));
}
QAction* voxelPaintColor = addActionToQMenuAndActionHash(toolsMenu,
MenuOption::VoxelPaintColor,
Qt::META | Qt::Key_C,
this,
SLOT(chooseVoxelPaintColor()));
Application::getInstance()->getSwatch()->setAction(voxelPaintColor);
QColor paintColor(128, 128, 128);
voxelPaintColor->setData(paintColor);
voxelPaintColor->setIcon(Swatch::createIcon(paintColor));
addActionToQMenuAndActionHash(toolsMenu,
MenuOption::DecreaseVoxelSize,
QKeySequence::ZoomOut,
@ -220,9 +220,9 @@ Menu::Menu() :
SLOT(increaseVoxelSize()));
addActionToQMenuAndActionHash(toolsMenu, MenuOption::ResetSwatchColors, 0, this, SLOT(resetSwatchColors()));
QMenu* viewMenu = addMenu("View");
addCheckableActionToQMenuAndActionHash(viewMenu,
MenuOption::Fullscreen,
Qt::CTRL | Qt::META | Qt::Key_F,
@ -233,10 +233,10 @@ Menu::Menu() :
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Mirror, Qt::SHIFT | Qt::Key_H);
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FullscreenMirror, Qt::Key_H);
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Enable3DTVMode, 0, false);
QMenu* avatarSizeMenu = viewMenu->addMenu("Avatar Size");
addActionToQMenuAndActionHash(avatarSizeMenu,
MenuOption::IncreaseAvatarSize,
Qt::Key_Plus,
@ -263,8 +263,8 @@ Menu::Menu() :
true);
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::MoveWithLean, 0, false);
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::HeadMouse, 0, false);
addDisabledActionAndSeparator(viewMenu, "Stats");
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Stats, Qt::Key_Slash);
addActionToQMenuAndActionHash(viewMenu, MenuOption::Log, Qt::CTRL | Qt::Key_L, appInstance, SLOT(toggleLogDialog()));
@ -272,7 +272,7 @@ Menu::Menu() :
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Bandwidth, 0, true);
addActionToQMenuAndActionHash(viewMenu, MenuOption::BandwidthDetails, 0, this, SLOT(bandwidthDetails()));
addActionToQMenuAndActionHash(viewMenu, MenuOption::VoxelStats, 0, this, SLOT(voxelStatsDetails()));
QMenu* developerMenu = addMenu("Developer");
QMenu* renderOptionsMenu = developerMenu->addMenu("Rendering Options");
@ -284,11 +284,11 @@ Menu::Menu() :
0,
appInstance->getGlowEffect(),
SLOT(cycleRenderMode()));
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::ParticleCloud, 0, false);
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Shadows, 0, false);
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Metavoxels, 0, false);
QMenu* voxelOptionsMenu = developerMenu->addMenu("Voxel Options");
@ -301,19 +301,20 @@ Menu::Menu() :
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DontRenderVoxels);
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DontCallOpenGLForVoxels);
_useVoxelShader = addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::UseVoxelShader, 0,
_useVoxelShader = addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::UseVoxelShader, 0,
false, appInstance->getVoxels(), SLOT(setUseVoxelShader(bool)));
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::VoxelsAsPoints, 0,
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::VoxelsAsPoints, 0,
false, appInstance->getVoxels(), SLOT(setVoxelsAsPoints(bool)));
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::VoxelTextures);
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::AmbientOcclusion);
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DontFadeOnVoxelServerChanges);
addActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::LodTools, Qt::SHIFT | Qt::Key_L, this, SLOT(lodTools()));
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DisableLocalVoxelCache);
QMenu* voxelProtoOptionsMenu = voxelOptionsMenu->addMenu("Voxel Server Protocol Options");
addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::DisableColorVoxels);
addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::DisableLowRes);
addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::DisableDeltaSending);
@ -322,16 +323,16 @@ Menu::Menu() :
addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::DestructiveAddVoxel);
QMenu* avatarOptionsMenu = developerMenu->addMenu("Avatar Options");
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::Avatars, 0, true);
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::CollisionProxies);
addActionToQMenuAndActionHash(avatarOptionsMenu,
MenuOption::FaceMode,
0,
&appInstance->getAvatar()->getHead().getVideoFace(),
SLOT(cycleRenderMode()));
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::LookAtVectors, 0, true);
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::LookAtIndicator, 0, true);
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu,
@ -375,12 +376,12 @@ Menu::Menu() :
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::SimulateLeapHand);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayLeapHands, 0, true);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::LeapDrive, 0, false);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::BallFromHand, 0, false);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::VoxelDrumming, 0, false);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::PlaySlaps, 0, false);
QMenu* trackingOptionsMenu = developerMenu->addMenu("Tracking Options");
addCheckableActionToQMenuAndActionHash(trackingOptionsMenu,
@ -389,14 +390,14 @@ Menu::Menu() :
false,
appInstance->getWebcam(),
SLOT(setSkeletonTrackingOn(bool)));
addCheckableActionToQMenuAndActionHash(trackingOptionsMenu,
MenuOption::LEDTracking,
0,
false,
appInstance->getWebcam()->getGrabber(),
SLOT(setLEDTrackingOn(bool)));
addDisabledActionAndSeparator(developerMenu, "Testing");
QMenu* timingMenu = developerMenu->addMenu("Timing and Statistics Tools");
@ -408,7 +409,7 @@ Menu::Menu() :
Qt::SHIFT | Qt::Key_S,
appInstance->getVoxels(),
SLOT(collectStatsForTreesAndVBOs()));
QMenu* frustumMenu = developerMenu->addMenu("View Frustum Debugging Tools");
addCheckableActionToQMenuAndActionHash(frustumMenu, MenuOption::DisplayFrustum, Qt::SHIFT | Qt::Key_F);
addActionToQMenuAndActionHash(frustumMenu,
@ -417,8 +418,8 @@ Menu::Menu() :
this,
SLOT(cycleFrustumRenderMode()));
updateFrustumRenderModeAction();
QMenu* renderDebugMenu = developerMenu->addMenu("Render Debugging Tools");
addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::PipelineWarnings, Qt::CTRL | Qt::SHIFT | Qt::Key_P);
addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::SuppressShortTimings, Qt::CTRL | Qt::SHIFT | Qt::Key_S);
@ -431,48 +432,48 @@ Menu::Menu() :
Qt::CTRL | Qt::Key_A,
appInstance->getVoxels(),
SLOT(showAllLocalVoxels()));
addActionToQMenuAndActionHash(renderDebugMenu,
MenuOption::KillLocalVoxels,
Qt::CTRL | Qt::Key_K,
appInstance, SLOT(doKillLocalVoxels()));
addActionToQMenuAndActionHash(renderDebugMenu,
MenuOption::RandomizeVoxelColors,
Qt::CTRL | Qt::Key_R,
appInstance->getVoxels(),
SLOT(randomizeVoxelColors()));
addActionToQMenuAndActionHash(renderDebugMenu,
MenuOption::FalseColorRandomly,
0,
appInstance->getVoxels(),
SLOT(falseColorizeRandom()));
addActionToQMenuAndActionHash(renderDebugMenu,
MenuOption::FalseColorEveryOtherVoxel,
0,
appInstance->getVoxels(),
SLOT(falseColorizeRandomEveryOther()));
addActionToQMenuAndActionHash(renderDebugMenu,
MenuOption::FalseColorByDistance,
0,
appInstance->getVoxels(),
SLOT(falseColorizeDistanceFromView()));
addActionToQMenuAndActionHash(renderDebugMenu,
MenuOption::FalseColorOutOfView,
0,
appInstance->getVoxels(),
SLOT(falseColorizeInView()));
addActionToQMenuAndActionHash(renderDebugMenu,
MenuOption::FalseColorBySource,
0,
appInstance->getVoxels(),
SLOT(falseColorizeBySource()));
addActionToQMenuAndActionHash(renderDebugMenu,
MenuOption::ShowTrueColors,
Qt::CTRL | Qt::Key_T,
@ -485,32 +486,32 @@ Menu::Menu() :
0,
appInstance->getVoxels(),
SLOT(falseColorizeOccluded()));
addActionToQMenuAndActionHash(renderDebugMenu,
MenuOption::FalseColorOccludedV2,
0,
appInstance->getVoxels(),
SLOT(falseColorizeOccludedV2()));
addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::CoverageMap, Qt::SHIFT | Qt::CTRL | Qt::Key_O);
addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::CoverageMapV2, Qt::SHIFT | Qt::CTRL | Qt::Key_P);
QMenu* audioDebugMenu = developerMenu->addMenu("Audio Debugging Tools");
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoServerAudio);
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoLocalAudio);
addActionToQMenuAndActionHash(developerMenu, MenuOption::PasteToVoxel,
Qt::CTRL | Qt::SHIFT | Qt::Key_V,
addActionToQMenuAndActionHash(developerMenu, MenuOption::PasteToVoxel,
Qt::CTRL | Qt::SHIFT | Qt::Key_V,
this,
SLOT(pasteToVoxel()));
#ifndef Q_OS_MAC
QMenu* helpMenu = addMenu("Help");
QAction* helpAction = helpMenu->addAction(MenuOption::AboutApp);
connect(helpAction, SIGNAL(triggered()), this, SLOT(aboutApp()));
#endif
}
Menu::~Menu() {
@ -522,7 +523,7 @@ void Menu::loadSettings(QSettings* settings) {
if (!settings) {
settings = Application::getInstance()->getSettings();
}
_audioJitterBufferSamples = loadSetting(settings, "audioJitterBufferSamples", 0);
_fieldOfView = loadSetting(settings, "fieldOfView", DEFAULT_FIELD_OF_VIEW_DEGREES);
_faceshiftEyeDeflection = loadSetting(settings, "faceshiftEyeDeflection", DEFAULT_FACESHIFT_EYE_DEFLECTION);
@ -530,7 +531,7 @@ void Menu::loadSettings(QSettings* settings) {
_maxVoxelPacketsPerSecond = loadSetting(settings, "maxVoxelsPPS", DEFAULT_MAX_VOXEL_PPS);
_voxelSizeScale = loadSetting(settings, "voxelSizeScale", DEFAULT_OCTREE_SIZE_SCALE);
_boundaryLevelAdjust = loadSetting(settings, "boundaryLevelAdjust", 0);
settings->beginGroup("View Frustum Offset Camera");
// in case settings is corrupt or missing loadSetting() will check for NaN
_viewFrustumOffset.yaw = loadSetting(settings, "viewFrustumOffsetYaw", 0.0f);
@ -539,7 +540,7 @@ void Menu::loadSettings(QSettings* settings) {
_viewFrustumOffset.distance = loadSetting(settings, "viewFrustumOffsetDistance", 0.0f);
_viewFrustumOffset.up = loadSetting(settings, "viewFrustumOffsetUp", 0.0f);
settings->endGroup();
scanMenuBar(&loadAction, settings);
Application::getInstance()->getAvatar()->loadData(settings);
Application::getInstance()->getSwatch()->loadData(settings);
@ -552,7 +553,7 @@ void Menu::saveSettings(QSettings* settings) {
if (!settings) {
settings = Application::getInstance()->getSettings();
}
settings->setValue("audioJitterBufferSamples", _audioJitterBufferSamples);
settings->setValue("fieldOfView", _fieldOfView);
settings->setValue("faceshiftEyeDeflection", _faceshiftEyeDeflection);
@ -567,7 +568,7 @@ void Menu::saveSettings(QSettings* settings) {
settings->setValue("viewFrustumOffsetDistance", _viewFrustumOffset.distance);
settings->setValue("viewFrustumOffsetUp", _viewFrustumOffset.up);
settings->endGroup();
scanMenuBar(&saveAction, settings);
Application::getInstance()->getAvatar()->saveData(settings);
Application::getInstance()->getSwatch()->saveData(settings);
@ -612,7 +613,7 @@ void Menu::saveAction(QSettings* set, QAction* action) {
void Menu::scanMenuBar(settingsAction modifySetting, QSettings* set) {
QList<QMenu*> menus = this->findChildren<QMenu *>();
for (QList<QMenu *>::const_iterator it = menus.begin(); menus.end() != it; ++it) {
scanMenu(*it, modifySetting, set);
}
@ -620,7 +621,7 @@ void Menu::scanMenuBar(settingsAction modifySetting, QSettings* set) {
void Menu::scanMenu(QMenu* menu, settingsAction modifySetting, QSettings* set) {
QList<QAction*> actions = menu->actions();
set->beginGroup(menu->title());
for (QList<QAction *>::const_iterator it = actions.begin(); actions.end() != it; ++it) {
if ((*it)->menu()) {
@ -636,48 +637,48 @@ void Menu::scanMenu(QMenu* menu, settingsAction modifySetting, QSettings* set) {
void Menu::handleViewFrustumOffsetKeyModifier(int key) {
const float VIEW_FRUSTUM_OFFSET_DELTA = 0.5f;
const float VIEW_FRUSTUM_OFFSET_UP_DELTA = 0.05f;
switch (key) {
case Qt::Key_BracketLeft:
_viewFrustumOffset.yaw -= VIEW_FRUSTUM_OFFSET_DELTA;
break;
case Qt::Key_BracketRight:
_viewFrustumOffset.yaw += VIEW_FRUSTUM_OFFSET_DELTA;
break;
case Qt::Key_BraceLeft:
_viewFrustumOffset.pitch -= VIEW_FRUSTUM_OFFSET_DELTA;
break;
case Qt::Key_BraceRight:
_viewFrustumOffset.pitch += VIEW_FRUSTUM_OFFSET_DELTA;
break;
case Qt::Key_ParenLeft:
_viewFrustumOffset.roll -= VIEW_FRUSTUM_OFFSET_DELTA;
break;
case Qt::Key_ParenRight:
_viewFrustumOffset.roll += VIEW_FRUSTUM_OFFSET_DELTA;
break;
case Qt::Key_Less:
_viewFrustumOffset.distance -= VIEW_FRUSTUM_OFFSET_DELTA;
break;
case Qt::Key_Greater:
_viewFrustumOffset.distance += VIEW_FRUSTUM_OFFSET_DELTA;
break;
case Qt::Key_Comma:
_viewFrustumOffset.up -= VIEW_FRUSTUM_OFFSET_UP_DELTA;
break;
case Qt::Key_Period:
_viewFrustumOffset.up += VIEW_FRUSTUM_OFFSET_UP_DELTA;
break;
default:
break;
}
@ -695,7 +696,7 @@ QAction* Menu::addActionToQMenuAndActionHash(QMenu* destinationMenu,
const char* member,
QAction::MenuRole role) {
QAction* action;
if (receiver && member) {
action = destinationMenu->addAction(actionName, receiver, member, shortcut);
} else {
@ -703,9 +704,9 @@ QAction* Menu::addActionToQMenuAndActionHash(QMenu* destinationMenu,
action->setShortcut(shortcut);
}
action->setMenuRole(role);
_actionHash.insert(actionName, action);
return action;
}
@ -718,7 +719,7 @@ QAction* Menu::addCheckableActionToQMenuAndActionHash(QMenu* destinationMenu,
QAction* action = addActionToQMenuAndActionHash(destinationMenu, actionName, shortcut, receiver, member);
action->setCheckable(true);
action->setChecked(checked);
return action;
}
@ -755,7 +756,7 @@ void Menu::aboutApp() {
void sendFakeEnterEvent() {
QPoint lastCursorPosition = QCursor::pos();
QGLWidget* glWidget = Application::getInstance()->getGLWidget();
QPoint windowPosition = glWidget->mapFromGlobal(lastCursorPosition);
QEnterEvent enterEvent = QEnterEvent(windowPosition, windowPosition, lastCursorPosition);
QCoreApplication::sendEvent(glWidget, &enterEvent);
@ -772,62 +773,62 @@ void Menu::login() {
loginDialog.setTextValue(username);
loginDialog.setWindowFlags(Qt::Sheet);
loginDialog.resize(loginDialog.parentWidget()->size().width() * DIALOG_RATIO_OF_WINDOW, loginDialog.size().height());
int dialogReturn = loginDialog.exec();
if (dialogReturn == QDialog::Accepted && !loginDialog.textValue().isEmpty() && loginDialog.textValue() != username) {
// there has been a username change
// ask for a profile reset with the new username
Application::getInstance()->resetProfile(loginDialog.textValue());
}
sendFakeEnterEvent();
}
void Menu::editPreferences() {
Application* applicationInstance = Application::getInstance();
QDialog dialog(applicationInstance->getWindow());
dialog.setWindowTitle("Interface Preferences");
QBoxLayout* layout = new QBoxLayout(QBoxLayout::TopToBottom);
dialog.setLayout(layout);
QFormLayout* form = new QFormLayout();
layout->addLayout(form, 1);
QString faceURLString = applicationInstance->getProfile()->getFaceModelURL().toString();
QLineEdit* faceURLEdit = new QLineEdit(faceURLString);
faceURLEdit->setMinimumWidth(QLINE_MINIMUM_WIDTH);
form->addRow("Face URL:", faceURLEdit);
QString skeletonURLString = applicationInstance->getProfile()->getSkeletonModelURL().toString();
QLineEdit* skeletonURLEdit = new QLineEdit(skeletonURLString);
skeletonURLEdit->setMinimumWidth(QLINE_MINIMUM_WIDTH);
form->addRow("Skeleton URL:", skeletonURLEdit);
QSlider* pupilDilation = new QSlider(Qt::Horizontal);
pupilDilation->setValue(applicationInstance->getAvatar()->getHead().getPupilDilation() * pupilDilation->maximum());
form->addRow("Pupil Dilation:", pupilDilation);
QSlider* faceshiftEyeDeflection = new QSlider(Qt::Horizontal);
faceshiftEyeDeflection->setValue(_faceshiftEyeDeflection * faceshiftEyeDeflection->maximum());
form->addRow("Faceshift Eye Deflection:", faceshiftEyeDeflection);
QSpinBox* fieldOfView = new QSpinBox();
fieldOfView->setMaximum(180);
fieldOfView->setMinimum(1);
fieldOfView->setValue(_fieldOfView);
form->addRow("Vertical Field of View (Degrees):", fieldOfView);
QDoubleSpinBox* leanScale = new QDoubleSpinBox();
leanScale->setValue(applicationInstance->getAvatar()->getLeanScale());
form->addRow("Lean Scale:", leanScale);
QDoubleSpinBox* avatarScale = new QDoubleSpinBox();
avatarScale->setValue(applicationInstance->getAvatar()->getScale());
form->addRow("Avatar Scale:", avatarScale);
QSpinBox* audioJitterBufferSamples = new QSpinBox();
audioJitterBufferSamples->setMaximum(10000);
audioJitterBufferSamples->setMinimum(-10000);
@ -853,93 +854,93 @@ void Menu::editPreferences() {
maxVoxelsPPS->setSingleStep(STEP_MAX_VOXELS_PPS);
maxVoxelsPPS->setValue(_maxVoxelPacketsPerSecond);
form->addRow("Maximum Voxels Packets Per Second:", maxVoxelsPPS);
QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
dialog.connect(buttons, SIGNAL(accepted()), SLOT(accept()));
dialog.connect(buttons, SIGNAL(rejected()), SLOT(reject()));
layout->addWidget(buttons);
int ret = dialog.exec();
if (ret == QDialog::Accepted) {
QUrl faceModelURL(faceURLEdit->text());
if (faceModelURL.toString() != faceURLString) {
// change the faceModelURL in the profile, it will also update this user's BlendFace
applicationInstance->getProfile()->setFaceModelURL(faceModelURL);
// send the new face mesh URL to the data-server (if we have a client UUID)
DataServerClient::putValueForKey(DataServerKey::FaceMeshURL,
faceModelURL.toString().toLocal8Bit().constData());
}
QUrl skeletonModelURL(skeletonURLEdit->text());
if (skeletonModelURL.toString() != skeletonURLString) {
// change the skeletonModelURL in the profile, it will also update this user's Body
applicationInstance->getProfile()->setSkeletonModelURL(skeletonModelURL);
// send the new skeleton model URL to the data-server (if we have a client UUID)
DataServerClient::putValueForKey(DataServerKey::SkeletonURL,
skeletonModelURL.toString().toLocal8Bit().constData());
}
applicationInstance->getAvatar()->getHead().setPupilDilation(pupilDilation->value() / (float)pupilDilation->maximum());
_maxVoxels = maxVoxels->value();
applicationInstance->getVoxels()->setMaxVoxels(_maxVoxels);
_maxVoxelPacketsPerSecond = maxVoxelsPPS->value();
applicationInstance->getAvatar()->setLeanScale(leanScale->value());
applicationInstance->getAvatar()->setClampedTargetScale(avatarScale->value());
_audioJitterBufferSamples = audioJitterBufferSamples->value();
if (_audioJitterBufferSamples != 0) {
applicationInstance->getAudio()->setJitterBufferSamples(_audioJitterBufferSamples);
}
_fieldOfView = fieldOfView->value();
applicationInstance->resizeGL(applicationInstance->getGLWidget()->width(), applicationInstance->getGLWidget()->height());
_faceshiftEyeDeflection = faceshiftEyeDeflection->value() / (float)faceshiftEyeDeflection->maximum();
}
sendFakeEnterEvent();
}
void Menu::goToDomain() {
QString currentDomainHostname = NodeList::getInstance()->getDomainHostname();
if (NodeList::getInstance()->getDomainPort() != DEFAULT_DOMAIN_SERVER_PORT) {
// add the port to the currentDomainHostname string if it is custom
currentDomainHostname.append(QString(":%1").arg(NodeList::getInstance()->getDomainPort()));
}
QInputDialog domainDialog(Application::getInstance()->getWindow());
domainDialog.setWindowTitle("Go to Domain");
domainDialog.setLabelText("Domain server:");
domainDialog.setTextValue(currentDomainHostname);
domainDialog.setWindowFlags(Qt::Sheet);
domainDialog.resize(domainDialog.parentWidget()->size().width() * DIALOG_RATIO_OF_WINDOW, domainDialog.size().height());
int dialogReturn = domainDialog.exec();
if (dialogReturn == QDialog::Accepted) {
QString newHostname(DEFAULT_DOMAIN_HOSTNAME);
if (domainDialog.textValue().size() > 0) {
// the user input a new hostname, use that
newHostname = domainDialog.textValue();
}
// send a node kill request, indicating to other clients that they should play the "disappeared" effect
NodeList::getInstance()->sendKillNode(&NODE_TYPE_AVATAR_MIXER, 1);
// give our nodeList the new domain-server hostname
NodeList::getInstance()->setDomainHostname(domainDialog.textValue());
}
sendFakeEnterEvent();
}
@ -948,8 +949,8 @@ void Menu::goToLocation() {
glm::vec3 avatarPos = myAvatar->getPosition();
QString currentLocation = QString("%1, %2, %3").arg(QString::number(avatarPos.x),
QString::number(avatarPos.y), QString::number(avatarPos.z));
QInputDialog coordinateDialog(Application::getInstance()->getWindow());
coordinateDialog.setWindowTitle("Go to Location");
coordinateDialog.setLabelText("Coordinate as x,y,z:");
@ -960,10 +961,10 @@ void Menu::goToLocation() {
int dialogReturn = coordinateDialog.exec();
if (dialogReturn == QDialog::Accepted && !coordinateDialog.textValue().isEmpty()) {
QByteArray newCoordinates;
QString delimiterPattern(",");
QStringList coordinateItems = coordinateDialog.textValue().split(delimiterPattern);
const int NUMBER_OF_COORDINATE_ITEMS = 3;
const int X_ITEM = 0;
const int Y_ITEM = 1;
@ -973,17 +974,17 @@ void Menu::goToLocation() {
double y = coordinateItems[Y_ITEM].toDouble();
double z = coordinateItems[Z_ITEM].toDouble();
glm::vec3 newAvatarPos(x, y, z);
if (newAvatarPos != avatarPos) {
// send a node kill request, indicating to other clients that they should play the "disappeared" effect
NodeList::getInstance()->sendKillNode(&NODE_TYPE_AVATAR_MIXER, 1);
qDebug("Going To Location: %f, %f, %f...", x, y, z);
myAvatar->setPosition(newAvatarPos);
myAvatar->setPosition(newAvatarPos);
}
}
}
sendFakeEnterEvent();
}
@ -995,7 +996,7 @@ void Menu::goToUser() {
userDialog.setTextValue(username);
userDialog.setWindowFlags(Qt::Sheet);
userDialog.resize(userDialog.parentWidget()->size().width() * DIALOG_RATIO_OF_WINDOW, userDialog.size().height());
int dialogReturn = userDialog.exec();
if (dialogReturn == QDialog::Accepted && !userDialog.textValue().isEmpty()) {
// there's a username entered by the user, make a request to the data-server
@ -1003,7 +1004,7 @@ void Menu::goToUser() {
QStringList() << DataServerKey::Domain << DataServerKey::Position << DataServerKey::Orientation,
userDialog.textValue());
}
sendFakeEnterEvent();
}
@ -1014,15 +1015,15 @@ void Menu::pasteToVoxel() {
QString octalCode = "";
pasteToOctalCodeDialog.setTextValue(octalCode);
pasteToOctalCodeDialog.setWindowFlags(Qt::Sheet);
pasteToOctalCodeDialog.resize(pasteToOctalCodeDialog.parentWidget()->size().width() * DIALOG_RATIO_OF_WINDOW,
pasteToOctalCodeDialog.resize(pasteToOctalCodeDialog.parentWidget()->size().width() * DIALOG_RATIO_OF_WINDOW,
pasteToOctalCodeDialog.size().height());
int dialogReturn = pasteToOctalCodeDialog.exec();
if (dialogReturn == QDialog::Accepted && !pasteToOctalCodeDialog.textValue().isEmpty()) {
// we got an octalCode to paste to...
QString locationToPaste = pasteToOctalCodeDialog.textValue();
unsigned char* octalCodeDestination = hexStringToOctalCode(locationToPaste);
// check to see if it was a legit octcode...
if (locationToPaste == octalCodeToHexString(octalCodeDestination)) {
Application::getInstance()->pasteVoxelsToOctalCode(octalCodeDestination);
@ -1030,7 +1031,7 @@ void Menu::pasteToVoxel() {
qDebug() << "Problem with octcode...";
}
}
sendFakeEnterEvent();
}
@ -1039,7 +1040,7 @@ void Menu::bandwidthDetails() {
_bandwidthDialog = new BandwidthDialog(Application::getInstance()->getGLWidget(),
Application::getInstance()->getBandwidthMeter());
connect(_bandwidthDialog, SIGNAL(closed()), SLOT(bandwidthDetailsClosed()));
_bandwidthDialog->show();
}
_bandwidthDialog->raise();
@ -1112,7 +1113,7 @@ void Menu::updateVoxelModeActions() {
void Menu::chooseVoxelPaintColor() {
Application* appInstance = Application::getInstance();
QAction* paintColor = _actionHash.value(MenuOption::VoxelPaintColor);
QColor selected = QColorDialog::getColor(paintColor->data().value<QColor>(),
appInstance->getGLWidget(),
"Voxel Paint Color");
@ -1120,7 +1121,7 @@ void Menu::chooseVoxelPaintColor() {
paintColor->setData(selected);
paintColor->setIcon(Swatch::createIcon(selected));
}
// restore the main window's active state
appInstance->getWindow()->activateWindow();
}

View file

@ -44,12 +44,12 @@ class Menu : public QMenuBar, public AbstractMenuInterface {
public:
static Menu* getInstance();
~Menu();
bool isOptionChecked(const QString& menuOption);
void triggerOption(const QString& menuOption);
QAction* getActionForOption(const QString& menuOption);
bool isVoxelModeActionChecked();
float getAudioJitterBufferSamples() const { return _audioJitterBufferSamples; }
float getFieldOfView() const { return _fieldOfView; }
float getFaceshiftEyeDeflection() const { return _faceshiftEyeDeflection; }
@ -61,7 +61,7 @@ public:
int getMaxVoxels() const { return _maxVoxels; }
QAction* getUseVoxelShader() const { return _useVoxelShader; }
void handleViewFrustumOffsetKeyModifier(int key);
// User Tweakable LOD Items
@ -69,10 +69,10 @@ public:
float getVoxelSizeScale() const { return _voxelSizeScale; }
void setBoundaryLevelAdjust(int boundaryLevelAdjust);
int getBoundaryLevelAdjust() const { return _boundaryLevelAdjust; }
// User Tweakable PPS from Voxel Server
int getMaxVoxelPacketsPerSecond() const { return _maxVoxelPacketsPerSecond; }
virtual QMenu* getActiveScriptsMenu() { return _activeScriptsMenu;}
virtual QAction* addActionToQMenuAndActionHash(QMenu* destinationMenu,
const QString actionName,
@ -81,7 +81,7 @@ public:
const char* member = NULL,
QAction::MenuRole role = QAction::NoRole);
virtual void removeAction(QMenu* menu, const QString& actionName);
public slots:
void bandwidthDetails();
void voxelStatsDetails();
@ -92,7 +92,7 @@ public slots:
void exportSettings();
void goToUser();
void pasteToVoxel();
private slots:
void aboutApp();
void login();
@ -107,30 +107,30 @@ private slots:
void chooseVoxelPaintColor();
void runTests();
void resetSwatchColors();
private:
static Menu* _instance;
Menu();
typedef void(*settingsAction)(QSettings*, QAction*);
static void loadAction(QSettings* set, QAction* action);
static void saveAction(QSettings* set, QAction* action);
void scanMenuBar(settingsAction modifySetting, QSettings* set);
void scanMenu(QMenu* menu, settingsAction modifySetting, QSettings* set);
/// helper method to have separators with labels that are also compatible with OS X
void addDisabledActionAndSeparator(QMenu* destinationMenu, const QString& actionName);
QAction* addCheckableActionToQMenuAndActionHash(QMenu* destinationMenu,
const QString actionName,
const QKeySequence& shortcut = 0,
const bool checked = false,
const QObject* receiver = NULL,
const char* member = NULL);
void updateFrustumRenderModeAction();
QHash<QString, QAction*> _actionHash;
int _audioJitterBufferSamples; /// number of extra samples to wait before starting audio playback
BandwidthDialog* _bandwidthDialog;
@ -171,6 +171,7 @@ namespace MenuOption {
const QString DestructiveAddVoxel = "Create Voxel is Destructive";
const QString DisableColorVoxels = "Disable Colored Voxels";
const QString DisableDeltaSending = "Disable Delta Sending";
const QString DisableLocalVoxelCache = "Disable Local Voxel Cache";
const QString DisableLowRes = "Disable Lower Resolution While Moving";
const QString DisplayFrustum = "Display Frustum";
const QString DisplayLeapHands = "Display Leap Hands";