merge upstream with local repo

This commit is contained in:
Andrew Meadows 2014-01-15 17:13:59 -08:00
commit 2e1c2f3a61
4 changed files with 229 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); NodeList* nodeList = NodeList::createInstance(NODE_TYPE_AGENT, listenPort);
// connect our processDatagrams slot to the QUDPSocket readyRead() signal // connect our processDatagrams slot to the QUDPSocket readyRead() signal
connect(&nodeList->getNodeSocket(), SIGNAL(readyRead()), SLOT(processDatagrams())); 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())); connect(audioThread, SIGNAL(started()), &_audio, SLOT(start()));
audioThread->start(); audioThread->start();
connect(nodeList, SIGNAL(domainChanged(const QString&)), SLOT(domainChanged(const QString&))); connect(nodeList, SIGNAL(domainChanged(const QString&)), SLOT(domainChanged(const QString&)));
connect(nodeList, SIGNAL(nodeKilled(SharedNodePointer)), SLOT(nodeKilled(SharedNodePointer))); connect(nodeList, SIGNAL(nodeKilled(SharedNodePointer)), SLOT(nodeKilled(SharedNodePointer)));
@ -209,7 +209,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
#endif #endif
// tell the NodeList instance who to tell the domain server we care about // 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}; NODE_TYPE_PARTICLE_SERVER, NODE_TYPE_METAVOXEL_SERVER};
nodeList->setNodeTypesOfInterest(nodeTypesOfInterest, sizeof(nodeTypesOfInterest)); nodeList->setNodeTypesOfInterest(nodeTypesOfInterest, sizeof(nodeTypesOfInterest));
@ -1416,8 +1416,10 @@ void Application::terminate() {
_voxelHideShowThread.terminate(); _voxelHideShowThread.terminate();
_voxelEditSender.terminate(); _voxelEditSender.terminate();
_particleEditSender.terminate(); _particleEditSender.terminate();
_persistThread->terminate(); if (_persistThread) {
_persistThread = NULL; _persistThread->terminate();
_persistThread = NULL;
}
} }
static Avatar* processAvatarMessageHeader(unsigned char*& packetData, size_t& dataBytes) { 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) { if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) {
Avatar* avatar = (Avatar*)node->getLinkedData(); Avatar* avatar = (Avatar*)node->getLinkedData();
float distance; float distance;
if (avatar->findRayIntersection(mouseRayOrigin, mouseRayDirection, distance)) { if (avatar->findRayIntersection(mouseRayOrigin, mouseRayDirection, distance)) {
// rescale to compensate for head embiggening // rescale to compensate for head embiggening
eyePosition = (avatar->getHead().calculateAverageEyePosition() - avatar->getHead().getScalePivot()) * eyePosition = (avatar->getHead().calculateAverageEyePosition() - avatar->getHead().getScalePivot()) *
(avatar->getScale() / avatar->getHead().getScale()) + avatar->getHead().getScalePivot(); (avatar->getScale() / avatar->getHead().getScale()) + avatar->getHead().getScalePivot();
_lookatIndicatorScale = avatar->getHead().getScale(); _lookatIndicatorScale = avatar->getHead().getScale();
_lookatOtherPosition = avatar->getHead().getPosition(); _lookatOtherPosition = avatar->getHead().getPosition();
nodeUUID = avatar->getOwningNode()->getUUID(); nodeUUID = avatar->getOwningNode()->getUUID();
@ -1979,7 +1981,7 @@ Avatar* Application::findLookatTargetAvatar(const glm::vec3& mouseRayOrigin, con
} }
} }
} }
return NULL; return NULL;
} }
@ -2021,7 +2023,7 @@ void Application::renderHighlightVoxel(VoxelDetail voxel) {
void Application::updateAvatars(float deltaTime, glm::vec3 mouseRayOrigin, glm::vec3 mouseRayDirection) { void Application::updateAvatars(float deltaTime, glm::vec3 mouseRayOrigin, glm::vec3 mouseRayDirection) {
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
PerformanceWarning warn(showWarnings, "Application::updateAvatars()"); PerformanceWarning warn(showWarnings, "Application::updateAvatars()");
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
QMutexLocker(&node->getMutex()); QMutexLocker(&node->getMutex());
if (node->getLinkedData()) { 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++) { for (vector<Avatar*>::iterator fade = _avatarFades.begin(); fade != _avatarFades.end(); fade++) {
Avatar* avatar = *fade; Avatar* avatar = *fade;
const float SHRINK_RATE = 0.9f; const float SHRINK_RATE = 0.9f;
avatar->setTargetScale(avatar->getScale() * SHRINK_RATE); avatar->setTargetScale(avatar->getScale() * SHRINK_RATE);
const float MIN_FADE_SCALE = 0.001; const float MIN_FADE_SCALE = 0.001;
if (avatar->getTargetScale() < MIN_FADE_SCALE) { if (avatar->getTargetScale() < MIN_FADE_SCALE) {
delete avatar; delete avatar;
_avatarFades.erase(fade--); _avatarFades.erase(fade--);
@ -2260,6 +2262,7 @@ void Application::updateMouseVoxels(float deltaTime, glm::vec3& mouseRayOrigin,
} }
} }
void Application::updateHandAndTouch(float deltaTime) { void Application::updateHandAndTouch(float deltaTime) {
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
PerformanceWarning warn(showWarnings, "Application::updateHandAndTouch()"); PerformanceWarning warn(showWarnings, "Application::updateHandAndTouch()");
@ -2303,7 +2306,9 @@ void Application::updateThreads(float deltaTime) {
_voxelHideShowThread.threadRoutine(); _voxelHideShowThread.threadRoutine();
_voxelEditSender.threadRoutine(); _voxelEditSender.threadRoutine();
_particleEditSender.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 totalServers = 0;
int inViewServers = 0; int inViewServers = 0;
int unknownJurisdictionServers = 0; int unknownJurisdictionServers = 0;
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
// only send to the NodeTypes that are serverType // only send to the NodeTypes that are serverType
if (node->getActiveSocket() != NULL && node->getType() == serverType) { if (node->getActiveSocket() != NULL && node->getType() == serverType) {
totalServers++; totalServers++;
// get the server bounds for this server // get the server bounds for this server
QUuid nodeUUID = node->getUUID(); QUuid nodeUUID = node->getUUID();
// if we haven't heard from this voxel server, go ahead and send it a query, so we // if we haven't heard from this voxel server, go ahead and send it a query, so we
// can get the jurisdiction... // can get the jurisdiction...
if (jurisdictions.find(nodeUUID) == jurisdictions.end()) { if (jurisdictions.find(nodeUUID) == jurisdictions.end()) {
unknownJurisdictionServers++; unknownJurisdictionServers++;
} else { } else {
const JurisdictionMap& map = (jurisdictions)[nodeUUID]; const JurisdictionMap& map = (jurisdictions)[nodeUUID];
unsigned char* rootCode = map.getRootOctalCode(); unsigned char* rootCode = map.getRootOctalCode();
if (rootCode) { if (rootCode) {
VoxelPositionSize rootDetails; VoxelPositionSize rootDetails;
voxelDetailsForCode(rootCode, rootDetails); voxelDetailsForCode(rootCode, rootDetails);
AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s); AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
serverBounds.scale(TREE_SCALE); serverBounds.scale(TREE_SCALE);
ViewFrustum::location serverFrustumLocation = _viewFrustum.boxInFrustum(serverBounds); ViewFrustum::location serverFrustumLocation = _viewFrustum.boxInFrustum(serverBounds);
if (serverFrustumLocation != ViewFrustum::OUTSIDE) { if (serverFrustumLocation != ViewFrustum::OUTSIDE) {
inViewServers++; inViewServers++;
} }
@ -2671,20 +2676,20 @@ void Application::queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, Node
if (wantExtraDebugging && unknownJurisdictionServers > 0) { if (wantExtraDebugging && unknownJurisdictionServers > 0) {
qDebug("perServerPPS: %d perUnknownServer: %d", perServerPPS, perUnknownServer); qDebug("perServerPPS: %d perUnknownServer: %d", perServerPPS, perUnknownServer);
} }
NodeList* nodeList = NodeList::getInstance(); NodeList* nodeList = NodeList::getInstance();
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
// only send to the NodeTypes that are serverType // only send to the NodeTypes that are serverType
if (node->getActiveSocket() != NULL && node->getType() == serverType) { if (node->getActiveSocket() != NULL && node->getType() == serverType) {
// get the server bounds for this server // get the server bounds for this server
QUuid nodeUUID = node->getUUID(); QUuid nodeUUID = node->getUUID();
bool inView = false; bool inView = false;
bool unknownView = false; bool unknownView = false;
// if we haven't heard from this voxel server, go ahead and send it a query, so we // if we haven't heard from this voxel server, go ahead and send it a query, so we
// can get the jurisdiction... // can get the jurisdiction...
if (jurisdictions.find(nodeUUID) == jurisdictions.end()) { if (jurisdictions.find(nodeUUID) == jurisdictions.end()) {
@ -2694,15 +2699,15 @@ void Application::queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, Node
} }
} else { } else {
const JurisdictionMap& map = (jurisdictions)[nodeUUID]; const JurisdictionMap& map = (jurisdictions)[nodeUUID];
unsigned char* rootCode = map.getRootOctalCode(); unsigned char* rootCode = map.getRootOctalCode();
if (rootCode) { if (rootCode) {
VoxelPositionSize rootDetails; VoxelPositionSize rootDetails;
voxelDetailsForCode(rootCode, rootDetails); voxelDetailsForCode(rootCode, rootDetails);
AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s); AABox serverBounds(glm::vec3(rootDetails.x, rootDetails.y, rootDetails.z), rootDetails.s);
serverBounds.scale(TREE_SCALE); serverBounds.scale(TREE_SCALE);
ViewFrustum::location serverFrustumLocation = _viewFrustum.boxInFrustum(serverBounds); ViewFrustum::location serverFrustumLocation = _viewFrustum.boxInFrustum(serverBounds);
if (serverFrustumLocation != ViewFrustum::OUTSIDE) { if (serverFrustumLocation != ViewFrustum::OUTSIDE) {
inView = true; inView = true;
@ -2715,7 +2720,7 @@ void Application::queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, Node
} }
} }
} }
if (inView) { if (inView) {
_voxelQuery.setMaxOctreePacketsPerSecond(perServerPPS); _voxelQuery.setMaxOctreePacketsPerSecond(perServerPPS);
} else if (unknownView) { } 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 " qDebug() << "no known jurisdiction for node " << *node << ", give it budget of "
<< perUnknownServer << " to send us jurisdiction."; << perUnknownServer << " to send us jurisdiction.";
} }
// set the query's position/orientation to be degenerate in a manner that will get the scene quickly // 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 // 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 // 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... // set up the packet for sending...
unsigned char* endOfVoxelQueryPacket = voxelQueryPacket; unsigned char* endOfVoxelQueryPacket = voxelQueryPacket;
// insert packet type/version and node UUID // insert packet type/version and node UUID
endOfVoxelQueryPacket += populateTypeAndVersion(endOfVoxelQueryPacket, packetType); endOfVoxelQueryPacket += populateTypeAndVersion(endOfVoxelQueryPacket, packetType);
QByteArray ownerUUID = nodeList->getOwnerUUID().toRfc4122(); QByteArray ownerUUID = nodeList->getOwnerUUID().toRfc4122();
memcpy(endOfVoxelQueryPacket, ownerUUID.constData(), ownerUUID.size()); memcpy(endOfVoxelQueryPacket, ownerUUID.constData(), ownerUUID.size());
endOfVoxelQueryPacket += ownerUUID.size(); endOfVoxelQueryPacket += ownerUUID.size();
// encode the query data... // encode the query data...
endOfVoxelQueryPacket += _voxelQuery.getBroadcastData(endOfVoxelQueryPacket); endOfVoxelQueryPacket += _voxelQuery.getBroadcastData(endOfVoxelQueryPacket);
int packetLength = endOfVoxelQueryPacket - voxelQueryPacket; int packetLength = endOfVoxelQueryPacket - voxelQueryPacket;
// make sure we still have an active socket // make sure we still have an active socket
if (node->getActiveSocket()) { if (node->getActiveSocket()) {
nodeList->getNodeSocket().writeDatagram((char*) voxelQueryPacket, packetLength, nodeList->getNodeSocket().writeDatagram((char*) voxelQueryPacket, packetLength,
node->getActiveSocket()->getAddress(), node->getActiveSocket()->getPort()); node->getActiveSocket()->getAddress(), node->getActiveSocket()->getPort());
} }
// Feed number of bytes to corresponding channel of the bandwidth meter // Feed number of bytes to corresponding channel of the bandwidth meter
_bandwidthMeter.outputStream(BandwidthMeter::VOXELS).updateValue(packetLength); _bandwidthMeter.outputStream(BandwidthMeter::VOXELS).updateValue(packetLength);
} }
@ -3244,7 +3249,7 @@ void Application::displayOverlay() {
char nodes[100]; char nodes[100];
int totalAvatars = 0, totalServers = 0; int totalAvatars = 0, totalServers = 0;
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) { foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
node->getType() == NODE_TYPE_AGENT ? totalAvatars++ : totalServers++; 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 // Now handle voxel servers, since there could be more than one, we average their ping times
unsigned long totalPingVoxel = 0; unsigned long totalPingVoxel = 0;
int voxelServerCount = 0; int voxelServerCount = 0;
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
if (node->getType() == NODE_TYPE_VOXEL_SERVER) { if (node->getType() == NODE_TYPE_VOXEL_SERVER) {
totalPingVoxel += node->getPingMs(); totalPingVoxel += node->getPingMs();
@ -3368,7 +3373,7 @@ void Application::displayStats() {
} }
} }
} }
if (voxelServerCount) { if (voxelServerCount) {
pingVoxel = totalPingVoxel/voxelServerCount; pingVoxel = totalPingVoxel/voxelServerCount;
} }
@ -3704,10 +3709,10 @@ void Application::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) {
if (!selfAvatarOnly) { if (!selfAvatarOnly) {
// Render avatars of other nodes // Render avatars of other nodes
NodeList* nodeList = NodeList::getInstance(); NodeList* nodeList = NodeList::getInstance();
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
QMutexLocker(&node->getMutex()); QMutexLocker(&node->getMutex());
if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) { if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) {
Avatar *avatar = (Avatar *)node->getLinkedData(); Avatar *avatar = (Avatar *)node->getLinkedData();
if (!avatar->isInitialized()) { if (!avatar->isInitialized()) {
@ -4205,28 +4210,28 @@ void Application::processDatagrams() {
MAX_PACKET_SIZE, MAX_PACKET_SIZE,
senderSockAddr.getAddressPointer(), senderSockAddr.getAddressPointer(),
senderSockAddr.getPortPointer()))) { senderSockAddr.getPortPointer()))) {
_packetCount++; _packetCount++;
_bytesCount += bytesReceived; _bytesCount += bytesReceived;
if (packetVersionMatch(_incomingPacket)) { if (packetVersionMatch(_incomingPacket)) {
// only process this packet if we have a match on the packet version // only process this packet if we have a match on the packet version
switch (_incomingPacket[0]) { switch (_incomingPacket[0]) {
case PACKET_TYPE_TRANSMITTER_DATA_V2: case PACKET_TYPE_TRANSMITTER_DATA_V2:
// V2 = IOS transmitter app // V2 = IOS transmitter app
_myTransmitter.processIncomingData(_incomingPacket, bytesReceived); _myTransmitter.processIncomingData(_incomingPacket, bytesReceived);
break; break;
case PACKET_TYPE_MIXED_AUDIO: case PACKET_TYPE_MIXED_AUDIO:
QMetaObject::invokeMethod(&_audio, "addReceivedAudioToBuffer", Qt::QueuedConnection, QMetaObject::invokeMethod(&_audio, "addReceivedAudioToBuffer", Qt::QueuedConnection,
Q_ARG(QByteArray, QByteArray((char*) _incomingPacket, bytesReceived))); Q_ARG(QByteArray, QByteArray((char*) _incomingPacket, bytesReceived)));
break; break;
case PACKET_TYPE_PARTICLE_ADD_RESPONSE: case PACKET_TYPE_PARTICLE_ADD_RESPONSE:
// look up our ParticleEditHanders.... // look up our ParticleEditHanders....
ParticleEditHandle::handleAddResponse(_incomingPacket, bytesReceived); ParticleEditHandle::handleAddResponse(_incomingPacket, bytesReceived);
break; break;
case PACKET_TYPE_PARTICLE_DATA: case PACKET_TYPE_PARTICLE_DATA:
case PACKET_TYPE_VOXEL_DATA: case PACKET_TYPE_VOXEL_DATA:
case PACKET_TYPE_VOXEL_ERASE: case PACKET_TYPE_VOXEL_ERASE:
@ -4234,7 +4239,7 @@ void Application::processDatagrams() {
case PACKET_TYPE_ENVIRONMENT_DATA: { case PACKET_TYPE_ENVIRONMENT_DATA: {
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
"Application::networkReceive()... _voxelProcessor.queueReceivedPacket()"); "Application::networkReceive()... _voxelProcessor.queueReceivedPacket()");
bool wantExtraDebugging = getLogger()->extraDebugging(); bool wantExtraDebugging = getLogger()->extraDebugging();
if (wantExtraDebugging && _incomingPacket[0] == PACKET_TYPE_VOXEL_DATA) { if (wantExtraDebugging && _incomingPacket[0] == PACKET_TYPE_VOXEL_DATA) {
int numBytesPacketHeader = numBytesForPacketHeader(_incomingPacket); int numBytesPacketHeader = numBytesForPacketHeader(_incomingPacket);
@ -4246,10 +4251,10 @@ void Application::processDatagrams() {
dataAt += sizeof(VOXEL_PACKET_SENT_TIME); dataAt += sizeof(VOXEL_PACKET_SENT_TIME);
VOXEL_PACKET_SENT_TIME arrivedAt = usecTimestampNow(); VOXEL_PACKET_SENT_TIME arrivedAt = usecTimestampNow();
int flightTime = arrivedAt - sentAt; int flightTime = arrivedAt - sentAt;
printf("got PACKET_TYPE_VOXEL_DATA, sequence:%d flightTime:%d\n", sequence, flightTime); 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 // add this packet to our list of voxel packets and process them on the voxel processing
_voxelProcessor.queueReceivedPacket(senderSockAddr, _incomingPacket, bytesReceived); _voxelProcessor.queueReceivedPacket(senderSockAddr, _incomingPacket, bytesReceived);
break; break;
@ -4392,10 +4397,13 @@ void Application::updateLocalOctreeCache(bool firstTime) {
QString localVoxelCacheFileName = getLocalVoxelCacheFileName(); QString localVoxelCacheFileName = getLocalVoxelCacheFileName();
const int LOCAL_CACHE_PERSIST_INTERVAL = 1000 * 10; // every 10 seconds 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) { if (_persistThread) {
_voxels.beginLoadingLocalVoxelCache(); // while local voxels are importing, don't do individual node VBO updates _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() { Menu* Menu::getInstance() {
static QMutex menuInstanceMutex; static QMutex menuInstanceMutex;
// lock the menu instance mutex to make sure we don't race and create two menus and crash // lock the menu instance mutex to make sure we don't race and create two menus and crash
menuInstanceMutex.lock(); menuInstanceMutex.lock();
if (!_instance) { if (!_instance) {
qDebug("First call to Menu::getInstance() - initing menu."); qDebug("First call to Menu::getInstance() - initing menu.");
_instance = new Menu(); _instance = new Menu();
} }
menuInstanceMutex.unlock(); menuInstanceMutex.unlock();
return _instance; return _instance;
} }
@ -72,9 +72,9 @@ Menu::Menu() :
_maxVoxelPacketsPerSecond(DEFAULT_MAX_VOXEL_PPS) _maxVoxelPacketsPerSecond(DEFAULT_MAX_VOXEL_PPS)
{ {
Application *appInstance = Application::getInstance(); Application *appInstance = Application::getInstance();
QMenu* fileMenu = addMenu("File"); QMenu* fileMenu = addMenu("File");
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
addActionToQMenuAndActionHash(fileMenu, addActionToQMenuAndActionHash(fileMenu,
MenuOption::AboutApp, MenuOption::AboutApp,
@ -83,7 +83,7 @@ Menu::Menu() :
SLOT(aboutApp()), SLOT(aboutApp()),
QAction::AboutRole); QAction::AboutRole);
#endif #endif
(addActionToQMenuAndActionHash(fileMenu, (addActionToQMenuAndActionHash(fileMenu,
MenuOption::Login, MenuOption::Login,
0, 0,
@ -97,7 +97,7 @@ Menu::Menu() :
addDisabledActionAndSeparator(fileMenu, "Voxels"); addDisabledActionAndSeparator(fileMenu, "Voxels");
addActionToQMenuAndActionHash(fileMenu, MenuOption::ExportVoxels, Qt::CTRL | Qt::Key_E, appInstance, SLOT(exportVoxels())); addActionToQMenuAndActionHash(fileMenu, MenuOption::ExportVoxels, Qt::CTRL | Qt::Key_E, appInstance, SLOT(exportVoxels()));
addActionToQMenuAndActionHash(fileMenu, MenuOption::ImportVoxels, Qt::CTRL | Qt::Key_I, appInstance, SLOT(importVoxels())); addActionToQMenuAndActionHash(fileMenu, MenuOption::ImportVoxels, Qt::CTRL | Qt::Key_I, appInstance, SLOT(importVoxels()));
addDisabledActionAndSeparator(fileMenu, "Go"); addDisabledActionAndSeparator(fileMenu, "Go");
addActionToQMenuAndActionHash(fileMenu, addActionToQMenuAndActionHash(fileMenu,
MenuOption::GoHome, MenuOption::GoHome,
@ -120,45 +120,45 @@ Menu::Menu() :
this, this,
SLOT(goToUser())); SLOT(goToUser()));
addDisabledActionAndSeparator(fileMenu, "Settings"); addDisabledActionAndSeparator(fileMenu, "Settings");
addActionToQMenuAndActionHash(fileMenu, MenuOption::SettingsImport, 0, this, SLOT(importSettings())); addActionToQMenuAndActionHash(fileMenu, MenuOption::SettingsImport, 0, this, SLOT(importSettings()));
addActionToQMenuAndActionHash(fileMenu, MenuOption::SettingsExport, 0, this, SLOT(exportSettings())); addActionToQMenuAndActionHash(fileMenu, MenuOption::SettingsExport, 0, this, SLOT(exportSettings()));
addDisabledActionAndSeparator(fileMenu, "Devices"); addDisabledActionAndSeparator(fileMenu, "Devices");
addActionToQMenuAndActionHash(fileMenu, MenuOption::Pair, 0, PairingHandler::getInstance(), SLOT(sendPairRequest())); addActionToQMenuAndActionHash(fileMenu, MenuOption::Pair, 0, PairingHandler::getInstance(), SLOT(sendPairRequest()));
addCheckableActionToQMenuAndActionHash(fileMenu, MenuOption::TransmitterDrive, 0, true); addCheckableActionToQMenuAndActionHash(fileMenu, MenuOption::TransmitterDrive, 0, true);
addActionToQMenuAndActionHash(fileMenu, addActionToQMenuAndActionHash(fileMenu,
MenuOption::Quit, MenuOption::Quit,
Qt::CTRL | Qt::Key_Q, Qt::CTRL | Qt::Key_Q,
appInstance, appInstance,
SLOT(quit()), SLOT(quit()),
QAction::QuitRole); QAction::QuitRole);
QMenu* editMenu = addMenu("Edit"); QMenu* editMenu = addMenu("Edit");
addActionToQMenuAndActionHash(editMenu, addActionToQMenuAndActionHash(editMenu,
MenuOption::Preferences, MenuOption::Preferences,
Qt::CTRL | Qt::Key_Comma, Qt::CTRL | Qt::Key_Comma,
this, this,
SLOT(editPreferences()), SLOT(editPreferences()),
QAction::PreferencesRole); QAction::PreferencesRole);
addDisabledActionAndSeparator(editMenu, "Voxels"); addDisabledActionAndSeparator(editMenu, "Voxels");
addActionToQMenuAndActionHash(editMenu, MenuOption::CutVoxels, Qt::CTRL | Qt::Key_X, appInstance, SLOT(cutVoxels())); 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::CopyVoxels, Qt::CTRL | Qt::Key_C, appInstance, SLOT(copyVoxels()));
addActionToQMenuAndActionHash(editMenu, MenuOption::PasteVoxels, Qt::CTRL | Qt::Key_V, appInstance, SLOT(pasteVoxels())); addActionToQMenuAndActionHash(editMenu, MenuOption::PasteVoxels, Qt::CTRL | Qt::Key_V, appInstance, SLOT(pasteVoxels()));
addActionToQMenuAndActionHash(editMenu, MenuOption::NudgeVoxels, Qt::CTRL | Qt::Key_N, appInstance, SLOT(nudgeVoxels())); addActionToQMenuAndActionHash(editMenu, MenuOption::NudgeVoxels, Qt::CTRL | Qt::Key_N, appInstance, SLOT(nudgeVoxels()));
#ifdef __APPLE__ #ifdef __APPLE__
addActionToQMenuAndActionHash(editMenu, MenuOption::DeleteVoxels, Qt::Key_Backspace, appInstance, SLOT(deleteVoxels())); addActionToQMenuAndActionHash(editMenu, MenuOption::DeleteVoxels, Qt::Key_Backspace, appInstance, SLOT(deleteVoxels()));
#else #else
addActionToQMenuAndActionHash(editMenu, MenuOption::DeleteVoxels, Qt::Key_Delete, appInstance, SLOT(deleteVoxels())); addActionToQMenuAndActionHash(editMenu, MenuOption::DeleteVoxels, Qt::Key_Delete, appInstance, SLOT(deleteVoxels()));
#endif #endif
addDisabledActionAndSeparator(editMenu, "Physics"); addDisabledActionAndSeparator(editMenu, "Physics");
addCheckableActionToQMenuAndActionHash(editMenu, MenuOption::Gravity, Qt::SHIFT | Qt::Key_G, true); addCheckableActionToQMenuAndActionHash(editMenu, MenuOption::Gravity, Qt::SHIFT | Qt::Key_G, true);
addCheckableActionToQMenuAndActionHash(editMenu, addCheckableActionToQMenuAndActionHash(editMenu,
@ -167,47 +167,47 @@ Menu::Menu() :
true, true,
appInstance->getAvatar(), appInstance->getAvatar(),
SLOT(setWantCollisionsOn(bool))); SLOT(setWantCollisionsOn(bool)));
QMenu* toolsMenu = addMenu("Tools"); QMenu* toolsMenu = addMenu("Tools");
_voxelModeActionsGroup = new QActionGroup(this); _voxelModeActionsGroup = new QActionGroup(this);
_voxelModeActionsGroup->setExclusive(false); _voxelModeActionsGroup->setExclusive(false);
QAction* addVoxelMode = addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::VoxelAddMode, Qt::Key_V); QAction* addVoxelMode = addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::VoxelAddMode, Qt::Key_V);
_voxelModeActionsGroup->addAction(addVoxelMode); _voxelModeActionsGroup->addAction(addVoxelMode);
QAction* deleteVoxelMode = addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::VoxelDeleteMode, Qt::Key_R); QAction* deleteVoxelMode = addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::VoxelDeleteMode, Qt::Key_R);
_voxelModeActionsGroup->addAction(deleteVoxelMode); _voxelModeActionsGroup->addAction(deleteVoxelMode);
QAction* colorVoxelMode = addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::VoxelColorMode, Qt::Key_B); QAction* colorVoxelMode = addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::VoxelColorMode, Qt::Key_B);
_voxelModeActionsGroup->addAction(colorVoxelMode); _voxelModeActionsGroup->addAction(colorVoxelMode);
QAction* selectVoxelMode = addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::VoxelSelectMode, Qt::Key_O); QAction* selectVoxelMode = addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::VoxelSelectMode, Qt::Key_O);
_voxelModeActionsGroup->addAction(selectVoxelMode); _voxelModeActionsGroup->addAction(selectVoxelMode);
QAction* getColorMode = addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::VoxelGetColorMode, Qt::Key_G); QAction* getColorMode = addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::VoxelGetColorMode, Qt::Key_G);
_voxelModeActionsGroup->addAction(getColorMode); _voxelModeActionsGroup->addAction(getColorMode);
addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::ClickToFly); addCheckableActionToQMenuAndActionHash(toolsMenu, MenuOption::ClickToFly);
// connect each of the voxel mode actions to the updateVoxelModeActionsSlot // connect each of the voxel mode actions to the updateVoxelModeActionsSlot
foreach (QAction* action, _voxelModeActionsGroup->actions()) { foreach (QAction* action, _voxelModeActionsGroup->actions()) {
connect(action, SIGNAL(triggered()), this, SLOT(updateVoxelModeActions())); connect(action, SIGNAL(triggered()), this, SLOT(updateVoxelModeActions()));
} }
QAction* voxelPaintColor = addActionToQMenuAndActionHash(toolsMenu, QAction* voxelPaintColor = addActionToQMenuAndActionHash(toolsMenu,
MenuOption::VoxelPaintColor, MenuOption::VoxelPaintColor,
Qt::META | Qt::Key_C, Qt::META | Qt::Key_C,
this, this,
SLOT(chooseVoxelPaintColor())); SLOT(chooseVoxelPaintColor()));
Application::getInstance()->getSwatch()->setAction(voxelPaintColor); Application::getInstance()->getSwatch()->setAction(voxelPaintColor);
QColor paintColor(128, 128, 128); QColor paintColor(128, 128, 128);
voxelPaintColor->setData(paintColor); voxelPaintColor->setData(paintColor);
voxelPaintColor->setIcon(Swatch::createIcon(paintColor)); voxelPaintColor->setIcon(Swatch::createIcon(paintColor));
addActionToQMenuAndActionHash(toolsMenu, addActionToQMenuAndActionHash(toolsMenu,
MenuOption::DecreaseVoxelSize, MenuOption::DecreaseVoxelSize,
QKeySequence::ZoomOut, QKeySequence::ZoomOut,
@ -220,9 +220,9 @@ Menu::Menu() :
SLOT(increaseVoxelSize())); SLOT(increaseVoxelSize()));
addActionToQMenuAndActionHash(toolsMenu, MenuOption::ResetSwatchColors, 0, this, SLOT(resetSwatchColors())); addActionToQMenuAndActionHash(toolsMenu, MenuOption::ResetSwatchColors, 0, this, SLOT(resetSwatchColors()));
QMenu* viewMenu = addMenu("View"); QMenu* viewMenu = addMenu("View");
addCheckableActionToQMenuAndActionHash(viewMenu, addCheckableActionToQMenuAndActionHash(viewMenu,
MenuOption::Fullscreen, MenuOption::Fullscreen,
Qt::CTRL | Qt::META | Qt::Key_F, 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::Mirror, Qt::SHIFT | Qt::Key_H);
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FullscreenMirror, Qt::Key_H); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::FullscreenMirror, Qt::Key_H);
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Enable3DTVMode, 0, false); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Enable3DTVMode, 0, false);
QMenu* avatarSizeMenu = viewMenu->addMenu("Avatar Size"); QMenu* avatarSizeMenu = viewMenu->addMenu("Avatar Size");
addActionToQMenuAndActionHash(avatarSizeMenu, addActionToQMenuAndActionHash(avatarSizeMenu,
MenuOption::IncreaseAvatarSize, MenuOption::IncreaseAvatarSize,
Qt::Key_Plus, Qt::Key_Plus,
@ -263,8 +263,8 @@ Menu::Menu() :
true); true);
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::MoveWithLean, 0, false); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::MoveWithLean, 0, false);
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::HeadMouse, 0, false); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::HeadMouse, 0, false);
addDisabledActionAndSeparator(viewMenu, "Stats"); addDisabledActionAndSeparator(viewMenu, "Stats");
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Stats, Qt::Key_Slash); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Stats, Qt::Key_Slash);
addActionToQMenuAndActionHash(viewMenu, MenuOption::Log, Qt::CTRL | Qt::Key_L, appInstance, SLOT(toggleLogDialog())); addActionToQMenuAndActionHash(viewMenu, MenuOption::Log, Qt::CTRL | Qt::Key_L, appInstance, SLOT(toggleLogDialog()));
@ -272,7 +272,7 @@ Menu::Menu() :
addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Bandwidth, 0, true); addCheckableActionToQMenuAndActionHash(viewMenu, MenuOption::Bandwidth, 0, true);
addActionToQMenuAndActionHash(viewMenu, MenuOption::BandwidthDetails, 0, this, SLOT(bandwidthDetails())); addActionToQMenuAndActionHash(viewMenu, MenuOption::BandwidthDetails, 0, this, SLOT(bandwidthDetails()));
addActionToQMenuAndActionHash(viewMenu, MenuOption::VoxelStats, 0, this, SLOT(voxelStatsDetails())); addActionToQMenuAndActionHash(viewMenu, MenuOption::VoxelStats, 0, this, SLOT(voxelStatsDetails()));
QMenu* developerMenu = addMenu("Developer"); QMenu* developerMenu = addMenu("Developer");
QMenu* renderOptionsMenu = developerMenu->addMenu("Rendering Options"); QMenu* renderOptionsMenu = developerMenu->addMenu("Rendering Options");
@ -284,11 +284,11 @@ Menu::Menu() :
0, 0,
appInstance->getGlowEffect(), appInstance->getGlowEffect(),
SLOT(cycleRenderMode())); SLOT(cycleRenderMode()));
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::ParticleCloud, 0, false); addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::ParticleCloud, 0, false);
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Shadows, 0, false); addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Shadows, 0, false);
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Metavoxels, 0, false); addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Metavoxels, 0, false);
QMenu* voxelOptionsMenu = developerMenu->addMenu("Voxel Options"); QMenu* voxelOptionsMenu = developerMenu->addMenu("Voxel Options");
@ -301,19 +301,20 @@ Menu::Menu() :
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DontRenderVoxels); addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DontRenderVoxels);
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DontCallOpenGLForVoxels); addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DontCallOpenGLForVoxels);
_useVoxelShader = addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::UseVoxelShader, 0, _useVoxelShader = addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::UseVoxelShader, 0,
false, appInstance->getVoxels(), SLOT(setUseVoxelShader(bool))); false, appInstance->getVoxels(), SLOT(setUseVoxelShader(bool)));
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::VoxelsAsPoints, 0, addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::VoxelsAsPoints, 0,
false, appInstance->getVoxels(), SLOT(setVoxelsAsPoints(bool))); false, appInstance->getVoxels(), SLOT(setVoxelsAsPoints(bool)));
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::VoxelTextures); addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::VoxelTextures);
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::AmbientOcclusion); addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::AmbientOcclusion);
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DontFadeOnVoxelServerChanges); addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DontFadeOnVoxelServerChanges);
addActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::LodTools, Qt::SHIFT | Qt::Key_L, this, SLOT(lodTools())); addActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::LodTools, Qt::SHIFT | Qt::Key_L, this, SLOT(lodTools()));
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DisableLocalVoxelCache);
QMenu* voxelProtoOptionsMenu = voxelOptionsMenu->addMenu("Voxel Server Protocol Options"); QMenu* voxelProtoOptionsMenu = voxelOptionsMenu->addMenu("Voxel Server Protocol Options");
addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::DisableColorVoxels); addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::DisableColorVoxels);
addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::DisableLowRes); addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::DisableLowRes);
addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::DisableDeltaSending); addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::DisableDeltaSending);
@ -322,16 +323,16 @@ Menu::Menu() :
addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::DestructiveAddVoxel); addCheckableActionToQMenuAndActionHash(voxelProtoOptionsMenu, MenuOption::DestructiveAddVoxel);
QMenu* avatarOptionsMenu = developerMenu->addMenu("Avatar Options"); QMenu* avatarOptionsMenu = developerMenu->addMenu("Avatar Options");
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::Avatars, 0, true); addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::Avatars, 0, true);
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::CollisionProxies); addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::CollisionProxies);
addActionToQMenuAndActionHash(avatarOptionsMenu, addActionToQMenuAndActionHash(avatarOptionsMenu,
MenuOption::FaceMode, MenuOption::FaceMode,
0, 0,
&appInstance->getAvatar()->getHead().getVideoFace(), &appInstance->getAvatar()->getHead().getVideoFace(),
SLOT(cycleRenderMode())); SLOT(cycleRenderMode()));
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::LookAtVectors, 0, true); addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::LookAtVectors, 0, true);
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::LookAtIndicator, 0, true); addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::LookAtIndicator, 0, true);
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, addCheckableActionToQMenuAndActionHash(avatarOptionsMenu,
@ -375,12 +376,12 @@ Menu::Menu() :
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::SimulateLeapHand); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::SimulateLeapHand);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayLeapHands, 0, true); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayLeapHands, 0, true);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::LeapDrive, 0, false); 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::BallFromHand, 0, false);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::VoxelDrumming, 0, false); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::VoxelDrumming, 0, false);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::PlaySlaps, 0, false); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::PlaySlaps, 0, false);
QMenu* trackingOptionsMenu = developerMenu->addMenu("Tracking Options"); QMenu* trackingOptionsMenu = developerMenu->addMenu("Tracking Options");
addCheckableActionToQMenuAndActionHash(trackingOptionsMenu, addCheckableActionToQMenuAndActionHash(trackingOptionsMenu,
@ -389,14 +390,14 @@ Menu::Menu() :
false, false,
appInstance->getWebcam(), appInstance->getWebcam(),
SLOT(setSkeletonTrackingOn(bool))); SLOT(setSkeletonTrackingOn(bool)));
addCheckableActionToQMenuAndActionHash(trackingOptionsMenu, addCheckableActionToQMenuAndActionHash(trackingOptionsMenu,
MenuOption::LEDTracking, MenuOption::LEDTracking,
0, 0,
false, false,
appInstance->getWebcam()->getGrabber(), appInstance->getWebcam()->getGrabber(),
SLOT(setLEDTrackingOn(bool))); SLOT(setLEDTrackingOn(bool)));
addDisabledActionAndSeparator(developerMenu, "Testing"); addDisabledActionAndSeparator(developerMenu, "Testing");
QMenu* timingMenu = developerMenu->addMenu("Timing and Statistics Tools"); QMenu* timingMenu = developerMenu->addMenu("Timing and Statistics Tools");
@ -408,7 +409,7 @@ Menu::Menu() :
Qt::SHIFT | Qt::Key_S, Qt::SHIFT | Qt::Key_S,
appInstance->getVoxels(), appInstance->getVoxels(),
SLOT(collectStatsForTreesAndVBOs())); SLOT(collectStatsForTreesAndVBOs()));
QMenu* frustumMenu = developerMenu->addMenu("View Frustum Debugging Tools"); QMenu* frustumMenu = developerMenu->addMenu("View Frustum Debugging Tools");
addCheckableActionToQMenuAndActionHash(frustumMenu, MenuOption::DisplayFrustum, Qt::SHIFT | Qt::Key_F); addCheckableActionToQMenuAndActionHash(frustumMenu, MenuOption::DisplayFrustum, Qt::SHIFT | Qt::Key_F);
addActionToQMenuAndActionHash(frustumMenu, addActionToQMenuAndActionHash(frustumMenu,
@ -417,8 +418,8 @@ Menu::Menu() :
this, this,
SLOT(cycleFrustumRenderMode())); SLOT(cycleFrustumRenderMode()));
updateFrustumRenderModeAction(); updateFrustumRenderModeAction();
QMenu* renderDebugMenu = developerMenu->addMenu("Render Debugging Tools"); QMenu* renderDebugMenu = developerMenu->addMenu("Render Debugging Tools");
addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::PipelineWarnings, Qt::CTRL | Qt::SHIFT | Qt::Key_P); addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::PipelineWarnings, Qt::CTRL | Qt::SHIFT | Qt::Key_P);
addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::SuppressShortTimings, Qt::CTRL | Qt::SHIFT | Qt::Key_S); addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::SuppressShortTimings, Qt::CTRL | Qt::SHIFT | Qt::Key_S);
@ -431,48 +432,48 @@ Menu::Menu() :
Qt::CTRL | Qt::Key_A, Qt::CTRL | Qt::Key_A,
appInstance->getVoxels(), appInstance->getVoxels(),
SLOT(showAllLocalVoxels())); SLOT(showAllLocalVoxels()));
addActionToQMenuAndActionHash(renderDebugMenu, addActionToQMenuAndActionHash(renderDebugMenu,
MenuOption::KillLocalVoxels, MenuOption::KillLocalVoxels,
Qt::CTRL | Qt::Key_K, Qt::CTRL | Qt::Key_K,
appInstance, SLOT(doKillLocalVoxels())); appInstance, SLOT(doKillLocalVoxels()));
addActionToQMenuAndActionHash(renderDebugMenu, addActionToQMenuAndActionHash(renderDebugMenu,
MenuOption::RandomizeVoxelColors, MenuOption::RandomizeVoxelColors,
Qt::CTRL | Qt::Key_R, Qt::CTRL | Qt::Key_R,
appInstance->getVoxels(), appInstance->getVoxels(),
SLOT(randomizeVoxelColors())); SLOT(randomizeVoxelColors()));
addActionToQMenuAndActionHash(renderDebugMenu, addActionToQMenuAndActionHash(renderDebugMenu,
MenuOption::FalseColorRandomly, MenuOption::FalseColorRandomly,
0, 0,
appInstance->getVoxels(), appInstance->getVoxels(),
SLOT(falseColorizeRandom())); SLOT(falseColorizeRandom()));
addActionToQMenuAndActionHash(renderDebugMenu, addActionToQMenuAndActionHash(renderDebugMenu,
MenuOption::FalseColorEveryOtherVoxel, MenuOption::FalseColorEveryOtherVoxel,
0, 0,
appInstance->getVoxels(), appInstance->getVoxels(),
SLOT(falseColorizeRandomEveryOther())); SLOT(falseColorizeRandomEveryOther()));
addActionToQMenuAndActionHash(renderDebugMenu, addActionToQMenuAndActionHash(renderDebugMenu,
MenuOption::FalseColorByDistance, MenuOption::FalseColorByDistance,
0, 0,
appInstance->getVoxels(), appInstance->getVoxels(),
SLOT(falseColorizeDistanceFromView())); SLOT(falseColorizeDistanceFromView()));
addActionToQMenuAndActionHash(renderDebugMenu, addActionToQMenuAndActionHash(renderDebugMenu,
MenuOption::FalseColorOutOfView, MenuOption::FalseColorOutOfView,
0, 0,
appInstance->getVoxels(), appInstance->getVoxels(),
SLOT(falseColorizeInView())); SLOT(falseColorizeInView()));
addActionToQMenuAndActionHash(renderDebugMenu, addActionToQMenuAndActionHash(renderDebugMenu,
MenuOption::FalseColorBySource, MenuOption::FalseColorBySource,
0, 0,
appInstance->getVoxels(), appInstance->getVoxels(),
SLOT(falseColorizeBySource())); SLOT(falseColorizeBySource()));
addActionToQMenuAndActionHash(renderDebugMenu, addActionToQMenuAndActionHash(renderDebugMenu,
MenuOption::ShowTrueColors, MenuOption::ShowTrueColors,
Qt::CTRL | Qt::Key_T, Qt::CTRL | Qt::Key_T,
@ -485,32 +486,32 @@ Menu::Menu() :
0, 0,
appInstance->getVoxels(), appInstance->getVoxels(),
SLOT(falseColorizeOccluded())); SLOT(falseColorizeOccluded()));
addActionToQMenuAndActionHash(renderDebugMenu, addActionToQMenuAndActionHash(renderDebugMenu,
MenuOption::FalseColorOccludedV2, MenuOption::FalseColorOccludedV2,
0, 0,
appInstance->getVoxels(), appInstance->getVoxels(),
SLOT(falseColorizeOccludedV2())); SLOT(falseColorizeOccludedV2()));
addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::CoverageMap, Qt::SHIFT | Qt::CTRL | Qt::Key_O); addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::CoverageMap, Qt::SHIFT | Qt::CTRL | Qt::Key_O);
addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::CoverageMapV2, Qt::SHIFT | Qt::CTRL | Qt::Key_P); addCheckableActionToQMenuAndActionHash(renderDebugMenu, MenuOption::CoverageMapV2, Qt::SHIFT | Qt::CTRL | Qt::Key_P);
QMenu* audioDebugMenu = developerMenu->addMenu("Audio Debugging Tools"); QMenu* audioDebugMenu = developerMenu->addMenu("Audio Debugging Tools");
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoServerAudio); addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoServerAudio);
addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoLocalAudio); addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::EchoLocalAudio);
addActionToQMenuAndActionHash(developerMenu, MenuOption::PasteToVoxel, addActionToQMenuAndActionHash(developerMenu, MenuOption::PasteToVoxel,
Qt::CTRL | Qt::SHIFT | Qt::Key_V, Qt::CTRL | Qt::SHIFT | Qt::Key_V,
this, this,
SLOT(pasteToVoxel())); SLOT(pasteToVoxel()));
#ifndef Q_OS_MAC #ifndef Q_OS_MAC
QMenu* helpMenu = addMenu("Help"); QMenu* helpMenu = addMenu("Help");
QAction* helpAction = helpMenu->addAction(MenuOption::AboutApp); QAction* helpAction = helpMenu->addAction(MenuOption::AboutApp);
connect(helpAction, SIGNAL(triggered()), this, SLOT(aboutApp())); connect(helpAction, SIGNAL(triggered()), this, SLOT(aboutApp()));
#endif #endif
} }
Menu::~Menu() { Menu::~Menu() {
@ -522,7 +523,7 @@ void Menu::loadSettings(QSettings* settings) {
if (!settings) { if (!settings) {
settings = Application::getInstance()->getSettings(); settings = Application::getInstance()->getSettings();
} }
_audioJitterBufferSamples = loadSetting(settings, "audioJitterBufferSamples", 0); _audioJitterBufferSamples = loadSetting(settings, "audioJitterBufferSamples", 0);
_fieldOfView = loadSetting(settings, "fieldOfView", DEFAULT_FIELD_OF_VIEW_DEGREES); _fieldOfView = loadSetting(settings, "fieldOfView", DEFAULT_FIELD_OF_VIEW_DEGREES);
_faceshiftEyeDeflection = loadSetting(settings, "faceshiftEyeDeflection", DEFAULT_FACESHIFT_EYE_DEFLECTION); _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); _maxVoxelPacketsPerSecond = loadSetting(settings, "maxVoxelsPPS", DEFAULT_MAX_VOXEL_PPS);
_voxelSizeScale = loadSetting(settings, "voxelSizeScale", DEFAULT_OCTREE_SIZE_SCALE); _voxelSizeScale = loadSetting(settings, "voxelSizeScale", DEFAULT_OCTREE_SIZE_SCALE);
_boundaryLevelAdjust = loadSetting(settings, "boundaryLevelAdjust", 0); _boundaryLevelAdjust = loadSetting(settings, "boundaryLevelAdjust", 0);
settings->beginGroup("View Frustum Offset Camera"); settings->beginGroup("View Frustum Offset Camera");
// in case settings is corrupt or missing loadSetting() will check for NaN // in case settings is corrupt or missing loadSetting() will check for NaN
_viewFrustumOffset.yaw = loadSetting(settings, "viewFrustumOffsetYaw", 0.0f); _viewFrustumOffset.yaw = loadSetting(settings, "viewFrustumOffsetYaw", 0.0f);
@ -539,7 +540,7 @@ void Menu::loadSettings(QSettings* settings) {
_viewFrustumOffset.distance = loadSetting(settings, "viewFrustumOffsetDistance", 0.0f); _viewFrustumOffset.distance = loadSetting(settings, "viewFrustumOffsetDistance", 0.0f);
_viewFrustumOffset.up = loadSetting(settings, "viewFrustumOffsetUp", 0.0f); _viewFrustumOffset.up = loadSetting(settings, "viewFrustumOffsetUp", 0.0f);
settings->endGroup(); settings->endGroup();
scanMenuBar(&loadAction, settings); scanMenuBar(&loadAction, settings);
Application::getInstance()->getAvatar()->loadData(settings); Application::getInstance()->getAvatar()->loadData(settings);
Application::getInstance()->getSwatch()->loadData(settings); Application::getInstance()->getSwatch()->loadData(settings);
@ -552,7 +553,7 @@ void Menu::saveSettings(QSettings* settings) {
if (!settings) { if (!settings) {
settings = Application::getInstance()->getSettings(); settings = Application::getInstance()->getSettings();
} }
settings->setValue("audioJitterBufferSamples", _audioJitterBufferSamples); settings->setValue("audioJitterBufferSamples", _audioJitterBufferSamples);
settings->setValue("fieldOfView", _fieldOfView); settings->setValue("fieldOfView", _fieldOfView);
settings->setValue("faceshiftEyeDeflection", _faceshiftEyeDeflection); settings->setValue("faceshiftEyeDeflection", _faceshiftEyeDeflection);
@ -567,7 +568,7 @@ void Menu::saveSettings(QSettings* settings) {
settings->setValue("viewFrustumOffsetDistance", _viewFrustumOffset.distance); settings->setValue("viewFrustumOffsetDistance", _viewFrustumOffset.distance);
settings->setValue("viewFrustumOffsetUp", _viewFrustumOffset.up); settings->setValue("viewFrustumOffsetUp", _viewFrustumOffset.up);
settings->endGroup(); settings->endGroup();
scanMenuBar(&saveAction, settings); scanMenuBar(&saveAction, settings);
Application::getInstance()->getAvatar()->saveData(settings); Application::getInstance()->getAvatar()->saveData(settings);
Application::getInstance()->getSwatch()->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) { void Menu::scanMenuBar(settingsAction modifySetting, QSettings* set) {
QList<QMenu*> menus = this->findChildren<QMenu *>(); QList<QMenu*> menus = this->findChildren<QMenu *>();
for (QList<QMenu *>::const_iterator it = menus.begin(); menus.end() != it; ++it) { for (QList<QMenu *>::const_iterator it = menus.begin(); menus.end() != it; ++it) {
scanMenu(*it, modifySetting, set); scanMenu(*it, modifySetting, set);
} }
@ -620,7 +621,7 @@ void Menu::scanMenuBar(settingsAction modifySetting, QSettings* set) {
void Menu::scanMenu(QMenu* menu, settingsAction modifySetting, QSettings* set) { void Menu::scanMenu(QMenu* menu, settingsAction modifySetting, QSettings* set) {
QList<QAction*> actions = menu->actions(); QList<QAction*> actions = menu->actions();
set->beginGroup(menu->title()); set->beginGroup(menu->title());
for (QList<QAction *>::const_iterator it = actions.begin(); actions.end() != it; ++it) { for (QList<QAction *>::const_iterator it = actions.begin(); actions.end() != it; ++it) {
if ((*it)->menu()) { if ((*it)->menu()) {
@ -636,48 +637,48 @@ void Menu::scanMenu(QMenu* menu, settingsAction modifySetting, QSettings* set) {
void Menu::handleViewFrustumOffsetKeyModifier(int key) { void Menu::handleViewFrustumOffsetKeyModifier(int key) {
const float VIEW_FRUSTUM_OFFSET_DELTA = 0.5f; const float VIEW_FRUSTUM_OFFSET_DELTA = 0.5f;
const float VIEW_FRUSTUM_OFFSET_UP_DELTA = 0.05f; const float VIEW_FRUSTUM_OFFSET_UP_DELTA = 0.05f;
switch (key) { switch (key) {
case Qt::Key_BracketLeft: case Qt::Key_BracketLeft:
_viewFrustumOffset.yaw -= VIEW_FRUSTUM_OFFSET_DELTA; _viewFrustumOffset.yaw -= VIEW_FRUSTUM_OFFSET_DELTA;
break; break;
case Qt::Key_BracketRight: case Qt::Key_BracketRight:
_viewFrustumOffset.yaw += VIEW_FRUSTUM_OFFSET_DELTA; _viewFrustumOffset.yaw += VIEW_FRUSTUM_OFFSET_DELTA;
break; break;
case Qt::Key_BraceLeft: case Qt::Key_BraceLeft:
_viewFrustumOffset.pitch -= VIEW_FRUSTUM_OFFSET_DELTA; _viewFrustumOffset.pitch -= VIEW_FRUSTUM_OFFSET_DELTA;
break; break;
case Qt::Key_BraceRight: case Qt::Key_BraceRight:
_viewFrustumOffset.pitch += VIEW_FRUSTUM_OFFSET_DELTA; _viewFrustumOffset.pitch += VIEW_FRUSTUM_OFFSET_DELTA;
break; break;
case Qt::Key_ParenLeft: case Qt::Key_ParenLeft:
_viewFrustumOffset.roll -= VIEW_FRUSTUM_OFFSET_DELTA; _viewFrustumOffset.roll -= VIEW_FRUSTUM_OFFSET_DELTA;
break; break;
case Qt::Key_ParenRight: case Qt::Key_ParenRight:
_viewFrustumOffset.roll += VIEW_FRUSTUM_OFFSET_DELTA; _viewFrustumOffset.roll += VIEW_FRUSTUM_OFFSET_DELTA;
break; break;
case Qt::Key_Less: case Qt::Key_Less:
_viewFrustumOffset.distance -= VIEW_FRUSTUM_OFFSET_DELTA; _viewFrustumOffset.distance -= VIEW_FRUSTUM_OFFSET_DELTA;
break; break;
case Qt::Key_Greater: case Qt::Key_Greater:
_viewFrustumOffset.distance += VIEW_FRUSTUM_OFFSET_DELTA; _viewFrustumOffset.distance += VIEW_FRUSTUM_OFFSET_DELTA;
break; break;
case Qt::Key_Comma: case Qt::Key_Comma:
_viewFrustumOffset.up -= VIEW_FRUSTUM_OFFSET_UP_DELTA; _viewFrustumOffset.up -= VIEW_FRUSTUM_OFFSET_UP_DELTA;
break; break;
case Qt::Key_Period: case Qt::Key_Period:
_viewFrustumOffset.up += VIEW_FRUSTUM_OFFSET_UP_DELTA; _viewFrustumOffset.up += VIEW_FRUSTUM_OFFSET_UP_DELTA;
break; break;
default: default:
break; break;
} }
@ -695,7 +696,7 @@ QAction* Menu::addActionToQMenuAndActionHash(QMenu* destinationMenu,
const char* member, const char* member,
QAction::MenuRole role) { QAction::MenuRole role) {
QAction* action; QAction* action;
if (receiver && member) { if (receiver && member) {
action = destinationMenu->addAction(actionName, receiver, member, shortcut); action = destinationMenu->addAction(actionName, receiver, member, shortcut);
} else { } else {
@ -703,9 +704,9 @@ QAction* Menu::addActionToQMenuAndActionHash(QMenu* destinationMenu,
action->setShortcut(shortcut); action->setShortcut(shortcut);
} }
action->setMenuRole(role); action->setMenuRole(role);
_actionHash.insert(actionName, action); _actionHash.insert(actionName, action);
return action; return action;
} }
@ -718,7 +719,7 @@ QAction* Menu::addCheckableActionToQMenuAndActionHash(QMenu* destinationMenu,
QAction* action = addActionToQMenuAndActionHash(destinationMenu, actionName, shortcut, receiver, member); QAction* action = addActionToQMenuAndActionHash(destinationMenu, actionName, shortcut, receiver, member);
action->setCheckable(true); action->setCheckable(true);
action->setChecked(checked); action->setChecked(checked);
return action; return action;
} }
@ -755,7 +756,7 @@ void Menu::aboutApp() {
void sendFakeEnterEvent() { void sendFakeEnterEvent() {
QPoint lastCursorPosition = QCursor::pos(); QPoint lastCursorPosition = QCursor::pos();
QGLWidget* glWidget = Application::getInstance()->getGLWidget(); QGLWidget* glWidget = Application::getInstance()->getGLWidget();
QPoint windowPosition = glWidget->mapFromGlobal(lastCursorPosition); QPoint windowPosition = glWidget->mapFromGlobal(lastCursorPosition);
QEnterEvent enterEvent = QEnterEvent(windowPosition, windowPosition, lastCursorPosition); QEnterEvent enterEvent = QEnterEvent(windowPosition, windowPosition, lastCursorPosition);
QCoreApplication::sendEvent(glWidget, &enterEvent); QCoreApplication::sendEvent(glWidget, &enterEvent);
@ -772,62 +773,62 @@ void Menu::login() {
loginDialog.setTextValue(username); loginDialog.setTextValue(username);
loginDialog.setWindowFlags(Qt::Sheet); loginDialog.setWindowFlags(Qt::Sheet);
loginDialog.resize(loginDialog.parentWidget()->size().width() * DIALOG_RATIO_OF_WINDOW, loginDialog.size().height()); loginDialog.resize(loginDialog.parentWidget()->size().width() * DIALOG_RATIO_OF_WINDOW, loginDialog.size().height());
int dialogReturn = loginDialog.exec(); int dialogReturn = loginDialog.exec();
if (dialogReturn == QDialog::Accepted && !loginDialog.textValue().isEmpty() && loginDialog.textValue() != username) { if (dialogReturn == QDialog::Accepted && !loginDialog.textValue().isEmpty() && loginDialog.textValue() != username) {
// there has been a username change // there has been a username change
// ask for a profile reset with the new username // ask for a profile reset with the new username
Application::getInstance()->resetProfile(loginDialog.textValue()); Application::getInstance()->resetProfile(loginDialog.textValue());
} }
sendFakeEnterEvent(); sendFakeEnterEvent();
} }
void Menu::editPreferences() { void Menu::editPreferences() {
Application* applicationInstance = Application::getInstance(); Application* applicationInstance = Application::getInstance();
QDialog dialog(applicationInstance->getWindow()); QDialog dialog(applicationInstance->getWindow());
dialog.setWindowTitle("Interface Preferences"); dialog.setWindowTitle("Interface Preferences");
QBoxLayout* layout = new QBoxLayout(QBoxLayout::TopToBottom); QBoxLayout* layout = new QBoxLayout(QBoxLayout::TopToBottom);
dialog.setLayout(layout); dialog.setLayout(layout);
QFormLayout* form = new QFormLayout(); QFormLayout* form = new QFormLayout();
layout->addLayout(form, 1); layout->addLayout(form, 1);
QString faceURLString = applicationInstance->getProfile()->getFaceModelURL().toString(); QString faceURLString = applicationInstance->getProfile()->getFaceModelURL().toString();
QLineEdit* faceURLEdit = new QLineEdit(faceURLString); QLineEdit* faceURLEdit = new QLineEdit(faceURLString);
faceURLEdit->setMinimumWidth(QLINE_MINIMUM_WIDTH); faceURLEdit->setMinimumWidth(QLINE_MINIMUM_WIDTH);
form->addRow("Face URL:", faceURLEdit); form->addRow("Face URL:", faceURLEdit);
QString skeletonURLString = applicationInstance->getProfile()->getSkeletonModelURL().toString(); QString skeletonURLString = applicationInstance->getProfile()->getSkeletonModelURL().toString();
QLineEdit* skeletonURLEdit = new QLineEdit(skeletonURLString); QLineEdit* skeletonURLEdit = new QLineEdit(skeletonURLString);
skeletonURLEdit->setMinimumWidth(QLINE_MINIMUM_WIDTH); skeletonURLEdit->setMinimumWidth(QLINE_MINIMUM_WIDTH);
form->addRow("Skeleton URL:", skeletonURLEdit); form->addRow("Skeleton URL:", skeletonURLEdit);
QSlider* pupilDilation = new QSlider(Qt::Horizontal); QSlider* pupilDilation = new QSlider(Qt::Horizontal);
pupilDilation->setValue(applicationInstance->getAvatar()->getHead().getPupilDilation() * pupilDilation->maximum()); pupilDilation->setValue(applicationInstance->getAvatar()->getHead().getPupilDilation() * pupilDilation->maximum());
form->addRow("Pupil Dilation:", pupilDilation); form->addRow("Pupil Dilation:", pupilDilation);
QSlider* faceshiftEyeDeflection = new QSlider(Qt::Horizontal); QSlider* faceshiftEyeDeflection = new QSlider(Qt::Horizontal);
faceshiftEyeDeflection->setValue(_faceshiftEyeDeflection * faceshiftEyeDeflection->maximum()); faceshiftEyeDeflection->setValue(_faceshiftEyeDeflection * faceshiftEyeDeflection->maximum());
form->addRow("Faceshift Eye Deflection:", faceshiftEyeDeflection); form->addRow("Faceshift Eye Deflection:", faceshiftEyeDeflection);
QSpinBox* fieldOfView = new QSpinBox(); QSpinBox* fieldOfView = new QSpinBox();
fieldOfView->setMaximum(180); fieldOfView->setMaximum(180);
fieldOfView->setMinimum(1); fieldOfView->setMinimum(1);
fieldOfView->setValue(_fieldOfView); fieldOfView->setValue(_fieldOfView);
form->addRow("Vertical Field of View (Degrees):", fieldOfView); form->addRow("Vertical Field of View (Degrees):", fieldOfView);
QDoubleSpinBox* leanScale = new QDoubleSpinBox(); QDoubleSpinBox* leanScale = new QDoubleSpinBox();
leanScale->setValue(applicationInstance->getAvatar()->getLeanScale()); leanScale->setValue(applicationInstance->getAvatar()->getLeanScale());
form->addRow("Lean Scale:", leanScale); form->addRow("Lean Scale:", leanScale);
QDoubleSpinBox* avatarScale = new QDoubleSpinBox(); QDoubleSpinBox* avatarScale = new QDoubleSpinBox();
avatarScale->setValue(applicationInstance->getAvatar()->getScale()); avatarScale->setValue(applicationInstance->getAvatar()->getScale());
form->addRow("Avatar Scale:", avatarScale); form->addRow("Avatar Scale:", avatarScale);
QSpinBox* audioJitterBufferSamples = new QSpinBox(); QSpinBox* audioJitterBufferSamples = new QSpinBox();
audioJitterBufferSamples->setMaximum(10000); audioJitterBufferSamples->setMaximum(10000);
audioJitterBufferSamples->setMinimum(-10000); audioJitterBufferSamples->setMinimum(-10000);
@ -853,93 +854,93 @@ void Menu::editPreferences() {
maxVoxelsPPS->setSingleStep(STEP_MAX_VOXELS_PPS); maxVoxelsPPS->setSingleStep(STEP_MAX_VOXELS_PPS);
maxVoxelsPPS->setValue(_maxVoxelPacketsPerSecond); maxVoxelsPPS->setValue(_maxVoxelPacketsPerSecond);
form->addRow("Maximum Voxels Packets Per Second:", maxVoxelsPPS); form->addRow("Maximum Voxels Packets Per Second:", maxVoxelsPPS);
QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); QDialogButtonBox* buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
dialog.connect(buttons, SIGNAL(accepted()), SLOT(accept())); dialog.connect(buttons, SIGNAL(accepted()), SLOT(accept()));
dialog.connect(buttons, SIGNAL(rejected()), SLOT(reject())); dialog.connect(buttons, SIGNAL(rejected()), SLOT(reject()));
layout->addWidget(buttons); layout->addWidget(buttons);
int ret = dialog.exec(); int ret = dialog.exec();
if (ret == QDialog::Accepted) { if (ret == QDialog::Accepted) {
QUrl faceModelURL(faceURLEdit->text()); QUrl faceModelURL(faceURLEdit->text());
if (faceModelURL.toString() != faceURLString) { if (faceModelURL.toString() != faceURLString) {
// change the faceModelURL in the profile, it will also update this user's BlendFace // change the faceModelURL in the profile, it will also update this user's BlendFace
applicationInstance->getProfile()->setFaceModelURL(faceModelURL); applicationInstance->getProfile()->setFaceModelURL(faceModelURL);
// send the new face mesh URL to the data-server (if we have a client UUID) // send the new face mesh URL to the data-server (if we have a client UUID)
DataServerClient::putValueForKey(DataServerKey::FaceMeshURL, DataServerClient::putValueForKey(DataServerKey::FaceMeshURL,
faceModelURL.toString().toLocal8Bit().constData()); faceModelURL.toString().toLocal8Bit().constData());
} }
QUrl skeletonModelURL(skeletonURLEdit->text()); QUrl skeletonModelURL(skeletonURLEdit->text());
if (skeletonModelURL.toString() != skeletonURLString) { if (skeletonModelURL.toString() != skeletonURLString) {
// change the skeletonModelURL in the profile, it will also update this user's Body // change the skeletonModelURL in the profile, it will also update this user's Body
applicationInstance->getProfile()->setSkeletonModelURL(skeletonModelURL); applicationInstance->getProfile()->setSkeletonModelURL(skeletonModelURL);
// send the new skeleton model URL to the data-server (if we have a client UUID) // send the new skeleton model URL to the data-server (if we have a client UUID)
DataServerClient::putValueForKey(DataServerKey::SkeletonURL, DataServerClient::putValueForKey(DataServerKey::SkeletonURL,
skeletonModelURL.toString().toLocal8Bit().constData()); skeletonModelURL.toString().toLocal8Bit().constData());
} }
applicationInstance->getAvatar()->getHead().setPupilDilation(pupilDilation->value() / (float)pupilDilation->maximum()); applicationInstance->getAvatar()->getHead().setPupilDilation(pupilDilation->value() / (float)pupilDilation->maximum());
_maxVoxels = maxVoxels->value(); _maxVoxels = maxVoxels->value();
applicationInstance->getVoxels()->setMaxVoxels(_maxVoxels); applicationInstance->getVoxels()->setMaxVoxels(_maxVoxels);
_maxVoxelPacketsPerSecond = maxVoxelsPPS->value(); _maxVoxelPacketsPerSecond = maxVoxelsPPS->value();
applicationInstance->getAvatar()->setLeanScale(leanScale->value()); applicationInstance->getAvatar()->setLeanScale(leanScale->value());
applicationInstance->getAvatar()->setClampedTargetScale(avatarScale->value()); applicationInstance->getAvatar()->setClampedTargetScale(avatarScale->value());
_audioJitterBufferSamples = audioJitterBufferSamples->value(); _audioJitterBufferSamples = audioJitterBufferSamples->value();
if (_audioJitterBufferSamples != 0) { if (_audioJitterBufferSamples != 0) {
applicationInstance->getAudio()->setJitterBufferSamples(_audioJitterBufferSamples); applicationInstance->getAudio()->setJitterBufferSamples(_audioJitterBufferSamples);
} }
_fieldOfView = fieldOfView->value(); _fieldOfView = fieldOfView->value();
applicationInstance->resizeGL(applicationInstance->getGLWidget()->width(), applicationInstance->getGLWidget()->height()); applicationInstance->resizeGL(applicationInstance->getGLWidget()->width(), applicationInstance->getGLWidget()->height());
_faceshiftEyeDeflection = faceshiftEyeDeflection->value() / (float)faceshiftEyeDeflection->maximum(); _faceshiftEyeDeflection = faceshiftEyeDeflection->value() / (float)faceshiftEyeDeflection->maximum();
} }
sendFakeEnterEvent(); sendFakeEnterEvent();
} }
void Menu::goToDomain() { void Menu::goToDomain() {
QString currentDomainHostname = NodeList::getInstance()->getDomainHostname(); QString currentDomainHostname = NodeList::getInstance()->getDomainHostname();
if (NodeList::getInstance()->getDomainPort() != DEFAULT_DOMAIN_SERVER_PORT) { if (NodeList::getInstance()->getDomainPort() != DEFAULT_DOMAIN_SERVER_PORT) {
// add the port to the currentDomainHostname string if it is custom // add the port to the currentDomainHostname string if it is custom
currentDomainHostname.append(QString(":%1").arg(NodeList::getInstance()->getDomainPort())); currentDomainHostname.append(QString(":%1").arg(NodeList::getInstance()->getDomainPort()));
} }
QInputDialog domainDialog(Application::getInstance()->getWindow()); QInputDialog domainDialog(Application::getInstance()->getWindow());
domainDialog.setWindowTitle("Go to Domain"); domainDialog.setWindowTitle("Go to Domain");
domainDialog.setLabelText("Domain server:"); domainDialog.setLabelText("Domain server:");
domainDialog.setTextValue(currentDomainHostname); domainDialog.setTextValue(currentDomainHostname);
domainDialog.setWindowFlags(Qt::Sheet); domainDialog.setWindowFlags(Qt::Sheet);
domainDialog.resize(domainDialog.parentWidget()->size().width() * DIALOG_RATIO_OF_WINDOW, domainDialog.size().height()); domainDialog.resize(domainDialog.parentWidget()->size().width() * DIALOG_RATIO_OF_WINDOW, domainDialog.size().height());
int dialogReturn = domainDialog.exec(); int dialogReturn = domainDialog.exec();
if (dialogReturn == QDialog::Accepted) { if (dialogReturn == QDialog::Accepted) {
QString newHostname(DEFAULT_DOMAIN_HOSTNAME); QString newHostname(DEFAULT_DOMAIN_HOSTNAME);
if (domainDialog.textValue().size() > 0) { if (domainDialog.textValue().size() > 0) {
// the user input a new hostname, use that // the user input a new hostname, use that
newHostname = domainDialog.textValue(); newHostname = domainDialog.textValue();
} }
// send a node kill request, indicating to other clients that they should play the "disappeared" effect // send a node kill request, indicating to other clients that they should play the "disappeared" effect
NodeList::getInstance()->sendKillNode(&NODE_TYPE_AVATAR_MIXER, 1); NodeList::getInstance()->sendKillNode(&NODE_TYPE_AVATAR_MIXER, 1);
// give our nodeList the new domain-server hostname // give our nodeList the new domain-server hostname
NodeList::getInstance()->setDomainHostname(domainDialog.textValue()); NodeList::getInstance()->setDomainHostname(domainDialog.textValue());
} }
sendFakeEnterEvent(); sendFakeEnterEvent();
} }
@ -948,8 +949,8 @@ void Menu::goToLocation() {
glm::vec3 avatarPos = myAvatar->getPosition(); glm::vec3 avatarPos = myAvatar->getPosition();
QString currentLocation = QString("%1, %2, %3").arg(QString::number(avatarPos.x), QString currentLocation = QString("%1, %2, %3").arg(QString::number(avatarPos.x),
QString::number(avatarPos.y), QString::number(avatarPos.z)); QString::number(avatarPos.y), QString::number(avatarPos.z));
QInputDialog coordinateDialog(Application::getInstance()->getWindow()); QInputDialog coordinateDialog(Application::getInstance()->getWindow());
coordinateDialog.setWindowTitle("Go to Location"); coordinateDialog.setWindowTitle("Go to Location");
coordinateDialog.setLabelText("Coordinate as x,y,z:"); coordinateDialog.setLabelText("Coordinate as x,y,z:");
@ -960,10 +961,10 @@ void Menu::goToLocation() {
int dialogReturn = coordinateDialog.exec(); int dialogReturn = coordinateDialog.exec();
if (dialogReturn == QDialog::Accepted && !coordinateDialog.textValue().isEmpty()) { if (dialogReturn == QDialog::Accepted && !coordinateDialog.textValue().isEmpty()) {
QByteArray newCoordinates; QByteArray newCoordinates;
QString delimiterPattern(","); QString delimiterPattern(",");
QStringList coordinateItems = coordinateDialog.textValue().split(delimiterPattern); QStringList coordinateItems = coordinateDialog.textValue().split(delimiterPattern);
const int NUMBER_OF_COORDINATE_ITEMS = 3; const int NUMBER_OF_COORDINATE_ITEMS = 3;
const int X_ITEM = 0; const int X_ITEM = 0;
const int Y_ITEM = 1; const int Y_ITEM = 1;
@ -973,17 +974,17 @@ void Menu::goToLocation() {
double y = coordinateItems[Y_ITEM].toDouble(); double y = coordinateItems[Y_ITEM].toDouble();
double z = coordinateItems[Z_ITEM].toDouble(); double z = coordinateItems[Z_ITEM].toDouble();
glm::vec3 newAvatarPos(x, y, z); glm::vec3 newAvatarPos(x, y, z);
if (newAvatarPos != avatarPos) { if (newAvatarPos != avatarPos) {
// send a node kill request, indicating to other clients that they should play the "disappeared" effect // send a node kill request, indicating to other clients that they should play the "disappeared" effect
NodeList::getInstance()->sendKillNode(&NODE_TYPE_AVATAR_MIXER, 1); NodeList::getInstance()->sendKillNode(&NODE_TYPE_AVATAR_MIXER, 1);
qDebug("Going To Location: %f, %f, %f...", x, y, z); qDebug("Going To Location: %f, %f, %f...", x, y, z);
myAvatar->setPosition(newAvatarPos); myAvatar->setPosition(newAvatarPos);
} }
} }
} }
sendFakeEnterEvent(); sendFakeEnterEvent();
} }
@ -995,7 +996,7 @@ void Menu::goToUser() {
userDialog.setTextValue(username); userDialog.setTextValue(username);
userDialog.setWindowFlags(Qt::Sheet); userDialog.setWindowFlags(Qt::Sheet);
userDialog.resize(userDialog.parentWidget()->size().width() * DIALOG_RATIO_OF_WINDOW, userDialog.size().height()); userDialog.resize(userDialog.parentWidget()->size().width() * DIALOG_RATIO_OF_WINDOW, userDialog.size().height());
int dialogReturn = userDialog.exec(); int dialogReturn = userDialog.exec();
if (dialogReturn == QDialog::Accepted && !userDialog.textValue().isEmpty()) { if (dialogReturn == QDialog::Accepted && !userDialog.textValue().isEmpty()) {
// there's a username entered by the user, make a request to the data-server // 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, QStringList() << DataServerKey::Domain << DataServerKey::Position << DataServerKey::Orientation,
userDialog.textValue()); userDialog.textValue());
} }
sendFakeEnterEvent(); sendFakeEnterEvent();
} }
@ -1014,15 +1015,15 @@ void Menu::pasteToVoxel() {
QString octalCode = ""; QString octalCode = "";
pasteToOctalCodeDialog.setTextValue(octalCode); pasteToOctalCodeDialog.setTextValue(octalCode);
pasteToOctalCodeDialog.setWindowFlags(Qt::Sheet); 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()); pasteToOctalCodeDialog.size().height());
int dialogReturn = pasteToOctalCodeDialog.exec(); int dialogReturn = pasteToOctalCodeDialog.exec();
if (dialogReturn == QDialog::Accepted && !pasteToOctalCodeDialog.textValue().isEmpty()) { if (dialogReturn == QDialog::Accepted && !pasteToOctalCodeDialog.textValue().isEmpty()) {
// we got an octalCode to paste to... // we got an octalCode to paste to...
QString locationToPaste = pasteToOctalCodeDialog.textValue(); QString locationToPaste = pasteToOctalCodeDialog.textValue();
unsigned char* octalCodeDestination = hexStringToOctalCode(locationToPaste); unsigned char* octalCodeDestination = hexStringToOctalCode(locationToPaste);
// check to see if it was a legit octcode... // check to see if it was a legit octcode...
if (locationToPaste == octalCodeToHexString(octalCodeDestination)) { if (locationToPaste == octalCodeToHexString(octalCodeDestination)) {
Application::getInstance()->pasteVoxelsToOctalCode(octalCodeDestination); Application::getInstance()->pasteVoxelsToOctalCode(octalCodeDestination);
@ -1030,7 +1031,7 @@ void Menu::pasteToVoxel() {
qDebug() << "Problem with octcode..."; qDebug() << "Problem with octcode...";
} }
} }
sendFakeEnterEvent(); sendFakeEnterEvent();
} }
@ -1039,7 +1040,7 @@ void Menu::bandwidthDetails() {
_bandwidthDialog = new BandwidthDialog(Application::getInstance()->getGLWidget(), _bandwidthDialog = new BandwidthDialog(Application::getInstance()->getGLWidget(),
Application::getInstance()->getBandwidthMeter()); Application::getInstance()->getBandwidthMeter());
connect(_bandwidthDialog, SIGNAL(closed()), SLOT(bandwidthDetailsClosed())); connect(_bandwidthDialog, SIGNAL(closed()), SLOT(bandwidthDetailsClosed()));
_bandwidthDialog->show(); _bandwidthDialog->show();
} }
_bandwidthDialog->raise(); _bandwidthDialog->raise();
@ -1112,7 +1113,7 @@ void Menu::updateVoxelModeActions() {
void Menu::chooseVoxelPaintColor() { void Menu::chooseVoxelPaintColor() {
Application* appInstance = Application::getInstance(); Application* appInstance = Application::getInstance();
QAction* paintColor = _actionHash.value(MenuOption::VoxelPaintColor); QAction* paintColor = _actionHash.value(MenuOption::VoxelPaintColor);
QColor selected = QColorDialog::getColor(paintColor->data().value<QColor>(), QColor selected = QColorDialog::getColor(paintColor->data().value<QColor>(),
appInstance->getGLWidget(), appInstance->getGLWidget(),
"Voxel Paint Color"); "Voxel Paint Color");
@ -1120,7 +1121,7 @@ void Menu::chooseVoxelPaintColor() {
paintColor->setData(selected); paintColor->setData(selected);
paintColor->setIcon(Swatch::createIcon(selected)); paintColor->setIcon(Swatch::createIcon(selected));
} }
// restore the main window's active state // restore the main window's active state
appInstance->getWindow()->activateWindow(); appInstance->getWindow()->activateWindow();
} }

View file

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

View file

@ -62,6 +62,9 @@ void OculusManager::connect() {
_scaleLocation = _program.uniformLocation("scale"); _scaleLocation = _program.uniformLocation("scale");
_scaleInLocation = _program.uniformLocation("scaleIn"); _scaleInLocation = _program.uniformLocation("scaleIn");
_hmdWarpParamLocation = _program.uniformLocation("hmdWarpParam"); _hmdWarpParamLocation = _program.uniformLocation("hmdWarpParam");
} else {
_deviceManager.Clear();
System::Destroy();
} }
#endif #endif
} }